一、NDEBUG 和 DEBUG宏的用法
1、
NDEBUG宏是Standard C中定义的宏,专门用来控制assert()的行为。如果定义了这个宏,则assert不会起作用。
#ifdef NDEBUG
#define assert(x) ((void)0)
#else
...
2、 C Standard中规定了assert以宏来实现。<assert.h>被设计来可以被多次包含,其中一上来就undef assert,然后由NDEBUG宏来决定其行为。如:
#ifdef NDEBUG将以上代码放在c/cpp最上方(当然,其后不能出现其它#include <assert.h>语句),就可以保证c/cpp所在的编译单元中的assert,在release下也会触发abort行为。
#undef NDEBUG
#include <assert.h>
#define NDEBUG
#else
#include <assert.h>
#endif // #ifdef NDEBUG
3、NDEBUG宏由于字面意思,也被用于作为判断debug/release版本的宏,不过这个是编译器、环境相关的,并不可靠。
比如vc中,对生成的release版本项目,默认会定义这个宏,而gcc并没有定义,得用-DNDEBUG参数来定义。
比如vc中,对生成的release版本项目,默认会定义这个宏,而gcc并没有定义,得用-DNDEBUG参数来定义。
4、C++ Standard中完全采用了C中的定义。
assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:
#include
void
assert的作用是现计算表达式
然后通过调用
请看下面的程序清单badptr.c:
#include
#include
#include
int
{
}
[root@localhost
[root@localhost
a.out:
使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
在调试结束后,可以通过在包含#include
#include
#define
#include
用法总结与注意事项:
1)在函数开始处检验传入参数的合法性
如:
int
{
//功能:改变缓冲区大小,
//参数:nNewSize
//返回值:缓冲区当前长度
//说明:保持原信息内容不变
assert(nNewSize
assert(nNewSize
...
}
2)每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败
不好:
好:
assert(nOffset+nSize
3)不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题
错误:
这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。
正确:
4)assert和后面的语句应空一行,以形成逻辑和视觉上的一致感
5)有的地方,assert不能代替条件过滤