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

时间:2008-10-31 11:28:33

标签: c++ assert

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

8 个答案:

答案 0 :(得分:34)

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

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

#include <assert.h>

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

    ...
}

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

assert(a++ == 5);

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

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

答案 1 :(得分:6)

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

它们用于确保您所期望的事情。

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

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

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

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

答案 2 :(得分:6)

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

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

}

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

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

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

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

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

答案 3 :(得分:3)

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

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

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

答案 4 :(得分:2)

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

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

答案 7 :(得分:0)

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

mypointer->myfunct();

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