15

c++中的断言是如何实现的?示例代码表示赞赏。

4

8 回答 8

35

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

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

#include <assert.h>

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

    ...
}

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

assert(a++ == 5);

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

assert((a == 5) && "a has the wrong value!!");
于 2008-10-31T11:34:30.013 回答
6

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

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

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

你编写了处理年龄的函数,你也“知道”你总是在传递合理的参数,然后你使用断言。这就像说“我知道这永远不会出错,但如果真的出错了,我想知道”,因为,嗯,每个人都会犯错。

因此,不要检查合理的用户输入,如果有可能出现问题的场景,请不要使用断言。进行真正的检查并处理错误。

断言通常仅用于调试构建,因此不要将具有副作用的代码放在断言中。

于 2008-10-31T11:33:25.103 回答
5

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

// 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 的默认实现不包含在发布运行时中。许多人(包括我自己)会使用的一种常见做法是将其替换为发布版本中包含的版本,但仅在诊断模式下调用。这可以通过完整的断言检查对发布版本进行适当的回归测试。我的版本如下;

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

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

这种技术的运行时开销很小,但它可以更轻松地跟踪任何使其进入该领域的错误。

于 2008-10-31T11:38:01.193 回答
3

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

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

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

于 2008-10-31T12:07:52.953 回答
2

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

于 2008-10-31T11:34:59.437 回答
1

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

于 2008-10-31T11:34:21.280 回答
1

这并没有解决从早期 C 时代就传给我们的断言工具,但是如果您的项目可以使用 Boost,您还应该了解Boost StaticAssert功能。

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

于 2008-10-31T16:24:04.140 回答
0

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

mypointer->myfunct();

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

于 2008-10-31T11:34:46.847 回答