什么是断言?你为什么要用它们?

时间:2022-11-18 19:00:47

How are assertions done in c++? Example code is appreciated.

如何在c ++中完成断言?示例代码表示赞赏。

8 个解决方案

#1


34  

Asserts are a way of explicitly checking the assumptions that your code makes, which helps you track down lots of bugs by narrowing down what the possible problems could be. They are typically only evaluated in a special "debug" build of your application, so they won't slow down the final release version.

断言是一种明确检查代码所做假设的方法,它可以通过缩小可能存在的问题来帮助您跟踪大量错误。它们通常仅在应用程序的特殊“调试”版本中进行评估,因此它们不会减慢最终版本的速度。

Let's say you wrote a function that took a pointer as an argument. There's a good chance that your code will assume that the pointer is non-NULL, so why not explicitly check that with an assertion? Here's how:

假设您编写了一个将指针作为参数的函数。你的代码很可能会假设指针是非NULL的,那么为什么不用断言显式检查呢?这是如何做:

#include <assert.h>

void function(int* pointer_arg)
{
    assert(pointer_arg != NULL);

    ...
}

An important thing to note is that the expressions you assert must never have side effects, since they won't be present in the release build. So never do something like this:

需要注意的一件重要事情是,断言的表达式必须永远不会产生副作用,因为它们不会出现在发布版本中。所以永远不要做这样的事情:

assert(a++ == 5);

Some people also like to add little messages into their assertions to help give them meaning. Since a string always evaulates to true, you could write this:

有些人还喜欢在他们的断言中添加一些消息,以帮助赋予他们意义。由于字符串总是evonlates为true,你可以这样写:

assert((a == 5) && "a has the wrong value!!");

#2


6  

Assertion are boolean expressions which should typically always be true.

断言是布尔表达式,通常应该总是为真。

They are used to ensure what you expected is also what happens.

它们用于确保您所期望的是什么。

void some_function(int age)
{
     assert(age > 0);
}

You wrote the function to deal with ages, you also 'know' for sure you're always passing sensible arguments, then you use an assert. It's like saying "I know this can never go wrong, but if it does, I want to know", because, well, everyone makes mistakes.

你编写了处理年龄的函数,你也'知道'肯定你总是传递合理的论点,然后你使用断言。这就像说“我知道这永远不会出错,但如果确实如此,我想知道”,因为,好吧,每个人都会犯错误。

So it's not to check for sensible user input, if there are scenario's where something can go wrong, don't use an assert. Do real checks and deal with the errors.

因此,不是要检查合理的用户输入,如果有情况可能出错,请不要使用断言。做真正的检查并处理错误。

Asserts are typically only for debug builds, so don't put code with side effects in asserts.

断言通常仅用于调试版本,因此不要在断言中添加带副作用的代码。

#3


6  

Assertions are used to verify design assumptions, usually in terms of input parameters and return results. For example

断言用于验证设计假设,通常根据输入参数和返回结果。例如

// Given customer and product details for a sale, generate an invoice

Invoice ProcessOrder(Customer Cust,Product Prod)
{
  assert(IsValid(Cust));
  assert(IsValid(Prod);
'
'
'
  assert(IsValid(RetInvoice))
   return(RetInvoice);

}

The assert statements aren't required for the code to run, but they check the validity of the input and output. If the input is invalid, there is a bug in the calling function. If the input is valid and output is invalid, there is a bug in this code. See design by contract for more details of this use of asserts.

代码运行不需要断言语句,但它们检查输入和输出的有效性。如果输入无效,则调用函数中存在错误。如果输入有效且输出无效,则此代码中存在错误。有关断言使用的更多详细信息,请参阅合同设计。

Edit: As pointed out in other posts, the default implementation of assert is not included in the release run-time. A common practice that many would use, including myself, is to replace it with a version that is included in the release build, but is only called in a diagnostics mode. This enables proper regression testing on release builds with full assertion checking. My version is as follows;

编辑:正如其他帖子所指出的,assert的默认实现不包含在发布运行时中。许多人会使用的常见做法(包括我自己)是将其替换为发布版本中包含的版本,但仅在诊断模式下调用。这样就可以通过完整的断言检查对发布版本进行适当的回归测试。我的版本如下;

extern  void _my_assert(void *, void *, unsigned);

#define myassert(exp)                               \
{                                                   \
    if (InDiagnostics)                              \
        if ( !(exp) )                               \
            _my_assert(#exp, __FILE__, __LINE__);   \
}                                                   \

There is a small runtime overhead in this technique, but it makes tracking any bugs that have made it into the field much easier.

这种技术有一个很小的运行时间开销,但它可以跟踪任何使其进入字段的错误变得更加容易。

#4


3  

Use assertions to check for "can't happen" situations.

使用断言来检查“不可能发生”的情况。

Typical usage: check against invalid/impossible arguments at the top of a function.

典型用法:检查函数顶部的无效/不可能参数。

Seldom seen, but still useful: loop invariants and postconditions.

很少看到,但仍然有用:循环不变量和后置条件。

#5


2  

Assertions are statements allowing you to test any assumptions you might have in your program. This is especially useful to document your program logic (preconditions and postconditions). Assertions that fail usually throw runtime errors, and are signs that something is VERY wrong with your program - your assertion failed because something you assumed to be true was not. The usual reasons are: there is a flaw in your function's logic, or the caller of your function passed you bad data.

断言是允许您测试程序中可能存在的任何假设的语句。这对于记录程序逻辑(前置条件和后置条件)特别有用。失败的断言通常会抛出运行时错误,并且表明程序出现问题非常严重 - 您的断言失败了,因为您认为真实的东西不是。通常的原因是:函数的逻辑存在缺陷,或者函数的调用者传递了错误的数据。

#6


1  

An assertion is something you add to your program that causes the program to stop immediately if a condition is met, and display an error message. You generally use them for things which you believe can never happen in your code.

断言是您添加到程序中的一种情况,它会导致程序在满足条件时立即停止,并显示错误消息。您通常将它们用于您认为在代码中永远不会发生的事情。

#7


1  

This doesn't address the assert facility which has come down to us from early C days, but you should also be aware of Boost StaticAssert functionality, in the event that your projects can use Boost.

这并不涉及从早期C日开始向我们提供的断言工具,但是如果您的项目可以使用Boost,您还应该了解Boost StaticAssert功能。

The standard C/C++ assert works during runtime. The Boost StaticAssert facility enables you to make some classes of assertions at compile time, catching logic errors and the like even earlier.

标准C / C ++断言在运行时运行。 Boost StaticAssert工具使您能够在编译时创建一些类断言,甚至更早地捕获逻辑错误等。

#8


0  

Here is a definition of what an assertion is and here is some sample code. In a nutshell an assertion is a way for a developer to test his (or her) assumptions about the state of the code at any given point. For example, if you were doing the following code:

这是一个断言是什么的定义,这里是一些示例代码。简而言之,断言是开发人员在任何给定点测试他(或她)关于代码状态的假设的一种方式。例如,如果您正在执行以下代码:

mypointer->myfunct();

You probably want to assert that mypointer is not NULL because that's your assumption--that mypointer will never be NULL before the call.

您可能想断言mypointer不是NULL,因为这是您的假设 - mypointer在调用之前永远不会为NULL。

#1


34  

Asserts are a way of explicitly checking the assumptions that your code makes, which helps you track down lots of bugs by narrowing down what the possible problems could be. They are typically only evaluated in a special "debug" build of your application, so they won't slow down the final release version.

断言是一种明确检查代码所做假设的方法,它可以通过缩小可能存在的问题来帮助您跟踪大量错误。它们通常仅在应用程序的特殊“调试”版本中进行评估,因此它们不会减慢最终版本的速度。

Let's say you wrote a function that took a pointer as an argument. There's a good chance that your code will assume that the pointer is non-NULL, so why not explicitly check that with an assertion? Here's how:

假设您编写了一个将指针作为参数的函数。你的代码很可能会假设指针是非NULL的,那么为什么不用断言显式检查呢?这是如何做:

#include <assert.h>

void function(int* pointer_arg)
{
    assert(pointer_arg != NULL);

    ...
}

An important thing to note is that the expressions you assert must never have side effects, since they won't be present in the release build. So never do something like this:

需要注意的一件重要事情是,断言的表达式必须永远不会产生副作用,因为它们不会出现在发布版本中。所以永远不要做这样的事情:

assert(a++ == 5);

Some people also like to add little messages into their assertions to help give them meaning. Since a string always evaulates to true, you could write this:

有些人还喜欢在他们的断言中添加一些消息,以帮助赋予他们意义。由于字符串总是evonlates为true,你可以这样写:

assert((a == 5) && "a has the wrong value!!");

#2


6  

Assertion are boolean expressions which should typically always be true.

断言是布尔表达式,通常应该总是为真。

They are used to ensure what you expected is also what happens.

它们用于确保您所期望的是什么。

void some_function(int age)
{
     assert(age > 0);
}

You wrote the function to deal with ages, you also 'know' for sure you're always passing sensible arguments, then you use an assert. It's like saying "I know this can never go wrong, but if it does, I want to know", because, well, everyone makes mistakes.

你编写了处理年龄的函数,你也'知道'肯定你总是传递合理的论点,然后你使用断言。这就像说“我知道这永远不会出错,但如果确实如此,我想知道”,因为,好吧,每个人都会犯错误。

So it's not to check for sensible user input, if there are scenario's where something can go wrong, don't use an assert. Do real checks and deal with the errors.

因此,不是要检查合理的用户输入,如果有情况可能出错,请不要使用断言。做真正的检查并处理错误。

Asserts are typically only for debug builds, so don't put code with side effects in asserts.

断言通常仅用于调试版本,因此不要在断言中添加带副作用的代码。

#3


6  

Assertions are used to verify design assumptions, usually in terms of input parameters and return results. For example

断言用于验证设计假设,通常根据输入参数和返回结果。例如

// Given customer and product details for a sale, generate an invoice

Invoice ProcessOrder(Customer Cust,Product Prod)
{
  assert(IsValid(Cust));
  assert(IsValid(Prod);
'
'
'
  assert(IsValid(RetInvoice))
   return(RetInvoice);

}

The assert statements aren't required for the code to run, but they check the validity of the input and output. If the input is invalid, there is a bug in the calling function. If the input is valid and output is invalid, there is a bug in this code. See design by contract for more details of this use of asserts.

代码运行不需要断言语句,但它们检查输入和输出的有效性。如果输入无效,则调用函数中存在错误。如果输入有效且输出无效,则此代码中存在错误。有关断言使用的更多详细信息,请参阅合同设计。

Edit: As pointed out in other posts, the default implementation of assert is not included in the release run-time. A common practice that many would use, including myself, is to replace it with a version that is included in the release build, but is only called in a diagnostics mode. This enables proper regression testing on release builds with full assertion checking. My version is as follows;

编辑:正如其他帖子所指出的,assert的默认实现不包含在发布运行时中。许多人会使用的常见做法(包括我自己)是将其替换为发布版本中包含的版本,但仅在诊断模式下调用。这样就可以通过完整的断言检查对发布版本进行适当的回归测试。我的版本如下;

extern  void _my_assert(void *, void *, unsigned);

#define myassert(exp)                               \
{                                                   \
    if (InDiagnostics)                              \
        if ( !(exp) )                               \
            _my_assert(#exp, __FILE__, __LINE__);   \
}                                                   \

There is a small runtime overhead in this technique, but it makes tracking any bugs that have made it into the field much easier.

这种技术有一个很小的运行时间开销,但它可以跟踪任何使其进入字段的错误变得更加容易。

#4


3  

Use assertions to check for "can't happen" situations.

使用断言来检查“不可能发生”的情况。

Typical usage: check against invalid/impossible arguments at the top of a function.

典型用法:检查函数顶部的无效/不可能参数。

Seldom seen, but still useful: loop invariants and postconditions.

很少看到,但仍然有用:循环不变量和后置条件。

#5


2  

Assertions are statements allowing you to test any assumptions you might have in your program. This is especially useful to document your program logic (preconditions and postconditions). Assertions that fail usually throw runtime errors, and are signs that something is VERY wrong with your program - your assertion failed because something you assumed to be true was not. The usual reasons are: there is a flaw in your function's logic, or the caller of your function passed you bad data.

断言是允许您测试程序中可能存在的任何假设的语句。这对于记录程序逻辑(前置条件和后置条件)特别有用。失败的断言通常会抛出运行时错误,并且表明程序出现问题非常严重 - 您的断言失败了,因为您认为真实的东西不是。通常的原因是:函数的逻辑存在缺陷,或者函数的调用者传递了错误的数据。

#6


1  

An assertion is something you add to your program that causes the program to stop immediately if a condition is met, and display an error message. You generally use them for things which you believe can never happen in your code.

断言是您添加到程序中的一种情况,它会导致程序在满足条件时立即停止,并显示错误消息。您通常将它们用于您认为在代码中永远不会发生的事情。

#7


1  

This doesn't address the assert facility which has come down to us from early C days, but you should also be aware of Boost StaticAssert functionality, in the event that your projects can use Boost.

这并不涉及从早期C日开始向我们提供的断言工具,但是如果您的项目可以使用Boost,您还应该了解Boost StaticAssert功能。

The standard C/C++ assert works during runtime. The Boost StaticAssert facility enables you to make some classes of assertions at compile time, catching logic errors and the like even earlier.

标准C / C ++断言在运行时运行。 Boost StaticAssert工具使您能够在编译时创建一些类断言,甚至更早地捕获逻辑错误等。

#8


0  

Here is a definition of what an assertion is and here is some sample code. In a nutshell an assertion is a way for a developer to test his (or her) assumptions about the state of the code at any given point. For example, if you were doing the following code:

这是一个断言是什么的定义,这里是一些示例代码。简而言之,断言是开发人员在任何给定点测试他(或她)关于代码状态的假设的一种方式。例如,如果您正在执行以下代码:

mypointer->myfunct();

You probably want to assert that mypointer is not NULL because that's your assumption--that mypointer will never be NULL before the call.

您可能想断言mypointer不是NULL,因为这是您的假设 - mypointer在调用之前永远不会为NULL。