什么是断言?你为什么要用它们? 如何在C++中进行断言?示例代码值得欣赏。

什么是断言?你为什么要用它们? 如何在C++中进行断言?示例代码值得欣赏。,c++,assert,C++,Assert,断言是布尔表达式,通常应始终为真 它们用于确保您所期望的也是发生的 void some_function(int age) { assert(age > 0); } 您编写了处理年龄的函数,您还“知道”确保始终传递合理的参数,然后使用断言。这就像说“我知道这永远不会出错,但如果出错,我想知道”,因为,每个人都会犯错 所以,这不是为了检查用户的合理输入,如果有可能出错的情况,不要使用断言。进行真正的检查并处理错误 断言通常只用于调试构建,因此不要将带有副作用的代码放入断言中 断言

断言是布尔表达式,通常应始终为真

它们用于确保您所期望的也是发生的

void some_function(int age)
{
     assert(age > 0);
}
您编写了处理年龄的函数,您还“知道”确保始终传递合理的参数,然后使用断言。这就像说“我知道这永远不会出错,但如果出错,我想知道”,因为,每个人都会犯错

所以,这不是为了检查用户的合理输入,如果有可能出错的情况,不要使用断言。进行真正的检查并处理错误


断言通常只用于调试构建,因此不要将带有副作用的代码放入断言中

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

断言是一种显式检查代码所做假设的方法,它通过缩小可能出现的问题的范围来帮助您跟踪许多错误。它们通常只在应用程序的特殊“调试”版本中进行评估,因此不会降低最终发布版本的速度

假设您编写了一个以指针作为参数的函数。您的代码很有可能假定指针为非NULL,那么为什么不使用断言显式地检查它呢?以下是方法:

#include <assert.h>

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

    ...
}
有些人还喜欢在他们的断言中添加一些小信息,以帮助赋予它们意义。由于字符串总是求值为true,您可以这样写:

assert((a == 5) && "a has the wrong value!!");
下面是一个断言是什么的示例代码。简言之,断言是开发人员在任何给定点测试他(或她)关于代码状态的假设的一种方法。例如,如果您正在执行以下代码:

mypointer->myfunct();

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

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

断言用于验证设计假设,通常是输入参数和返回结果。比如说

// 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);

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

编辑:正如在其他文章中指出的,assert的默认实现不包括在发布运行时中。包括我在内的许多人都会使用的一种常见做法是将其替换为发布版本中包含的版本,但仅在诊断模式下调用。这就允许在发布版本上进行适当的回归测试,并进行完整的断言检查。我的版本如下

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

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

这种技术的运行时开销很小,但它使跟踪任何使其进入该领域的bug变得更加容易。

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

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

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

这并没有解决从早期C时代就开始使用的断言功能,但是如果您的项目可以使用Boost,您还应该了解其功能


标准C/C++断言在运行时工作。Boost StaticAssert功能使您能够在编译时生成一些断言类,捕获逻辑错误等。我以前从未见过使用字符串进行anding的功能。真有用!在Perl语言中,这种技巧(或类似的变体)一直在使用,即使用给定的示例:a==5 | | die(“a的值错误”);为松散的布尔类型欢呼。这个字符串的另一个技巧是在版本代码中验证值,但在调试代码中断言。例如,首先使用if(x>10)检查,然后如果错误条件通过,只需断言(!“x超出边界”),然后打印到日志文件,等等@David:通常,assert语句会在失败时打印失败的条件以及文件/行信息。因此,它给你的是一个人类可读的信息以及实际的信息。同样,您可以使用两个参数编写自己的断言:一个条件和一条消息。David,您的IDE通常会将失败的表达式显示为向您显示的错误消息的一部分,因此,如果您的表达式包含字符串,则会弹出该字符串
extern  void _my_assert(void *, void *, unsigned);

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