ssert是只有定义了DEBUG才起作用的宏,如果其参数的计算结果为假,就中止调用程序的执行。
assert饼不是一个仓促拼凑起来的宏,为了不在程序的release和debug版本之间引起重要的差别,需要对其进行仔细的定义。宏assert不应该弄乱内存,不应该对未初始化的数据进行初始化,即它不应该产生其他副作用。正因为要求程序的debug版本和release版本行为完全相同,所以才不把assert作为函数,而把它做成宏。如果把assert做成函数的话,其调用就会引起不期望的内存或代码的兑换。要记住,使用assert的程序员是把它看成一个在任意系统状态下都可以安全使用的无害检测手段。
在同错误进行斗争时,每一点帮助都会有助于错误的发现。我们为什么要那些自己从来都用不着的灵活性呢?
#include <crtdefs.h>
#undef assert
#ifdef NDEBUG
#define assert(_Expression) ((void)0)
#else
#ifdef __cplusplus
extern "C" {
#endif
_CRTIMP void __cdecl _wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line);
#ifdef __cplusplus
}
#endif
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
#endif /* NDEBUG */
以上为我的VS2008里面assert.h
当assert失败时,他就会使用预处理程序根据宏_FILE_ _LINE_所提供的文件名和行号调用_wassert _wassert在标准错误输出设备stderr上打印一条错误信息,然后中止:
void _wassert(char * strFile , unsigned uLine)
{
fflush(stdout);
fprintf(stderr,”\nAssertion failed : %s,line %u\n”,srFile, uLIne);
fflush(stderr);
abort();
}
在执行abort之前,需要调用fflush将所有的缓冲输出写到标准输出设备stdout上。同样,如果stdout 和stderr 都将指向同一设备,fflush stdout仍然要放在fflush stderr之前,以确保只有在所有的输出都送到了stdout之后,fprintf才显示相应的错误信息。
不管断言宏最终是用什么样子方法定义的,都要使用它来对传递给相应函数的参数进行确认。如果在函数的每个调用点都对其进行参数进行检查,错误很快就会被发现。断言宏最好作用是使用户在错误发生时,就可以自动地把他们检查出来。
此外关于断言,也有两篇不错的文章
http://blog.csdn.net/donghai51arm/archive/2009/11/28/4897004.aspx
http://dev.firnow.com/course/3_program/c++/cppsl/200861/118777.html