如何在c ++中完成断言?示例代码表示赞赏。
答案 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)
这是断言的definition,here是一些示例代码。简而言之,断言是开发人员在任何给定点测试他(或她)关于代码状态的假设的一种方式。例如,如果您正在执行以下代码:
mypointer->myfunct();
您可能想断言mypointer不是NULL,因为这是您的假设 - mypointer在调用之前永远不会为NULL。