断言
运行时断言
断言(assertion)是一种编程中常用的手段。在通常情况下,断言就是将一个返回值总是需要为真的判别式放在语句中,用于排除在设计的逻辑上不应该产生的情况。比如一个函数总需要输入在一定的范围内的参数,那么程序员就可以对该参数使用断言,以迫使在该参数发生异常的时候程序退出,从而避免程序陷入逻辑的混乱。
从一些意义上讲,断言并不是正常程序所必需的,不过对于程序调试来说,通常断言能够帮助程序开发者快速定位那些违反了某些前提条件的程序错误。在 C++ 中,标准在 或 <assert.h> 头文件中为程序员提供了 assert 宏,用于在运行时进行断言。
#include<iostream>
#include<cassert>
char *arrayAlloc(int n)
{
assert(n > 0);
return new char [n]; // n如果小于0,永远不会执行到这里
}
int main()
{
char *a = arrayAlloc(-1);
return 0;
}
我们定义了一个 arrayAlloc 函数,该函数的唯一功能就是在堆上分配字节长度为 n 的数组并返回。为了避免意外发生,函数 arrayAlloc 对参数 n 进行了断言,要求其大于 0。而 main 函数中对 arrayAlloc 的使用却没有满足这个条件,那么在运行时,我们可以看到如下结果:
a.out: test.cpp:6: char* arrayAlloc(int): Assertion `n > 0' failed.
已放弃 (核心已转储)
预处理时
使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。可以定义宏 NDEBUG 来禁用 assert 宏,可以尽量避免程序退出的状况。实例代码如下:
#ifdef NDEBUG
# define assert(expr) ((void)0)
#else
...
#endif
一旦定义了 NDBUG 宏,assert 宏将被展开为一条无意义的 C 语句(通常会
被编译器优化掉)。