#ifdef NDEBUG #define assert(_Expression) ((void)0) #else /* NDEBUG */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ _CRTIMP void __cdecl _wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line); #ifdef __cplusplus } #endif /* __cplusplus */ #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) ) #endif /* NDEBUG */
- 原型定义:
● #include <assert.h>
● void assert( int expression );
#ifdef NDEBUG
#define assert(_Expression) ((void)0)
当调试完成后,如果定义了NDEBUG,关闭断言,优化生成的代码
assert的宏定义
代码如下:
#define assert(_Expression) (void)( (!!(_Expression)) ||
(_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
_Expresssion若为false,则!false=true,!true=false,此时继续执行||以后的语句,故会打印出出错信息,终止程序,若_Expression为true,则!true=false,!false=true,此时不再执行||以后的语句,故不会打印出信息 使用了||运算的截断 和 !!(_Expression)两次取否 ,#是把跟在后面的参数转换成一个字符串
_wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line);
#define NDEBUG
#include <assert.h>
- 最好使用assert宏检查一个条件,就是不要用&&或者||操作符,这样更容易发现是哪个条件出现问题,在需要的时候,多写几个assert宏。
- 不要使用assert进行变量修改,如assert(k++>10),因为我们可能会禁用这个宏,此时,k++是不会执行的,正如上面我们看到的一样。
- assert不是条件过滤。
#include<stdio.h>
#define assert(_Expression) (void)( (!!(_Expression)) || _assert(#_Expression, __FILE__, __LINE__), 0 )
void _assert(_Expression, __FILE__, __LINE__)
{
printf("Assertion Failed: %s, file%s line %d",_Expression, __FILE__, __LINE__);
abort();
}
(void)( (!!(_Expression)) || _assert(#_Expression, __FILE__, __LINE__), 0 )
- #exp会在预处理产生一个字符串.
- __FILE__,__LINE__,分别表示文件位置和行数。
- abort():这个函数是一个内部函数,它就是异常中止你运行的程序.