为什么要用断言?
首先要搞清楚为什么要用断言,不能看别人代码中有,就追赶时髦地用一用!从效果上来说assert断言能用if语句替换,那么为什么不用if语句把断言替换呢?一般而言,if语句是处理逻辑上的可能会发生的错误,断言则用来处理不应该发生的状况。
什么是不应该发的的状况呢?这要区分数据的来源:1、数据来源于系统内部(子程序、子模块间的调用)2、数据来源于系统外部(外部设备如键盘的输入、串口数据的读取、网络数据的读取)。对内部来源的数据,我们没法去通过常规的测试手段去验证,此时断言就用上了。
当然你如果硬是要用if语句也没人说你不对,但大量的if语句出现在源码中时,会造成代码臃肿,降低了可读性,另外会产生不紧凑代码,影响效率。
程序开发初期,码农们忽视的是程序间调用参数的合法性,对这些参数可使用断言来防止意外,随着程序进入release版时,可以定义NDEBUG来让断言失效。以下是NDEGBU对assert的处理代码。
#ifdef NDEBUG #define assert(expr) (static_cast<void> (0)) #else ...... #endif
如何使用断言?
assert宏是在标准库中提供的。它在库文件<cassert>中声明,它可以在程序中测试逻辑表达式,如果指定的逻辑表达式是false,assert()就会终止程序,并显示诊断消息。关闭断言使用#define NDEBUG,该语句会忽略转换单元中的所有断言语句。而且这个指令仅放在#include <cassert>之前才有效。示例如下:
#include <iostream> #define NDEBUG //关闭所有断言,必须放在#include <cassert>之前 #include <cassert> using namespace std; int main() { int a = 10, b = 2; //使用断言,若assert()中为false,则程序终止退出 assert(a < b); cout << a << b << endl; return 0; }
关于断言的使用原则
最后分享一下《代码大全》中对断言使用的建议:
1、用错误处理代码处理预期会发生的状况,用断言来处理绝不应该发生的状况;
2、避免把需要执行的代码放到断言中;
3、用断言来注解并验证前条件和后条件;
4、对于高健壮性的代码,应该先使用断言再处理错误 ;