如何在C++中完成断言?示例代码表示赞赏。什么是断言?你为什么要使用它们?
回答
断言是一种明确检查代码所作假设的方法,它通过缩小可能出现的问题来帮助您查找大量错误。它们通常仅在应用程序的特殊“调试”版本中进行评估,因此它们不会减慢最终发行版本的速度。
比方说,你写了一个函数,指针作为参数。你的代码很可能会假设指针是非NULL的,所以为什么不用断言来显式检查呢?具体方法如下:
#include <assert.h>
void function(int* pointer_arg)
{
assert(pointer_arg != NULL);
...
}
要注意的重要一点是,你断言表达式必须永远不会有副作用,因为它们不会出现在发布版本。所以千万不要这样做:
assert(a++ == 5);
有些人还喜欢在他们的断言中增加一点信息来帮助给他们意义。既然字符串总是evaulates为true,你可以这样写:
assert((a == 5) && "a has the wrong value!!");
断言是布尔表达式,通常应该是true。
他们用来确保你所期望的也是发生了什么。
void some_function(int age)
{
assert(age > 0);
}
你写的函数来处理年龄,你也“知道”为确保您总是传递明智的参数,然后使用断言。这就像说:“我知道这永远不会出错,但如果真的出现了,我想知道”,因为每个人都会犯错误。
因此,它不是检查明智的用户输入,如果有情况出现问题,请不要使用断言。做真正的检查并处理错误。
断言通常只用于调试版本,因此不要将代码与副作用置于断言中。
断言是您添加到您的程序,导致程序立即停止,如果条件满足,并显示一条错误消息。您通常将它们用于您认为在您的代码中永远不会发生的事情。
这里是一个什么样的断言和here是一些示例代码definition。简而言之,断言是开发人员在任何给定点测试他(或她)对代码状态假设的一种方式。例如,如果你在做下面的代码: - 这mypointer永远不会调用之前NULL
mypointer->myfunct();
你可能想断言,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);
}
断言语句不是代码运行所必需的,但它们检查输入和输出的有效性。如果输入无效,则调用函数中存在错误。如果输入有效且输出无效,则此代码中存在错误。请参阅design by contract以了解此断言使用的更多细节。
编辑:正如在其他文章中指出的,断言的默认实现不包含在发布运行时。包括我自己在内的很多人都会使用的一种常见做法是将其替换为发布版本中包含的版本,但只能在诊断模式下调用。这可以通过完全断言检查对发布版本进行适当的回归测试。我的版本如下;
extern void _my_assert(void *, void *, unsigned);
#define myassert(exp) \
{ \
if (InDiagnostics) \
if (!(exp)) \
_my_assert(#exp, __FILE__, __LINE__); \
} \
这种技术有一个很小的运行时间开销,但它使跟踪任何使它进入字段更容易的错误。
使用断言来检查“不能发生”的情况。
典型用法:检查函数顶部的无效/不可能参数。
很少见过,但仍然有用:循环不变量和后置条件。
这并没有解决断言设施,已经从早期的ç天回落到我们,但你也应该知道Boost StaticAssert功能,在您的项目可以使用加速事件。
标准C/C++断言在运行时工作。 Boost StaticAssert工具使您可以在编译时创建一些类的断言,甚至更早地捕获逻辑错误等。
- 1. 装配需要什么?为什么我们使用它们?
- 2. 什么是仿函数,为什么我们需要它们?
- 3. Windows上的Spark - 什么是winutils,为什么我们需要它?
- 4. 什么是伴侣对象,为什么我们需要它?
- 5. Maven快照究竟是什么,为什么我们需要它?
- 6. WOFF字体,它们是什么以及为什么要关心?
- 7. 什么是HostProtectionAttribute,我们为什么使用它?
- 8. 什么是压缩机模块?他们为什么重要?如何使用它?
- 9. 什么是扩展方法,为什么我们需要使用它?
- 10. 什么是表达树,您如何使用它们,以及为什么要使用它们?
- 11. 你为什么要用fmt.Sprint?
- 12. 什么是Autoconf?为什么人们使用它?我应该使用它吗?
- 13. 为什么断言:android.net.cts.ListeningPortsTest :: testNoListeningUdp6Ports
- 14. 为什么断言失败
- 15. 阅读宏:你用它们做什么?
- 16. 什么是依赖注入,为什么要使用它?
- 17. 什么是SEAM框架,我为什么要使用它?
- 18. 什么是.inc以及为什么要使用它?
- 19. 什么是检查点节点HDFS?为什么要使用它?
- 20. Bonjour是什么,我为什么要使用它?
- 21. 什么是语义标记,为什么要使用它?
- 22. 什么是无限迭代器?为什么要使用它?
- 23. GWT.create是什么意思,为什么要使用它?
- 24. 什么是MQ,我为什么要使用它?
- 25. 什么是动态代理类,为什么要使用它?
- 26. 什么是React Native?我为什么要使用它?
- 27. SQL,Postgres OID,它们是什么以及它们为什么有用?
- 28. ios sdk中的促销代码是什么?为什么我们使用它们?
- 29. 你为什么要使用umask?
- 30. 什么是http标题,什么时候需要指定它们
我还没有看到与字符串之前。真正有用! – 2008-10-31 11:36:26