#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():這個函數是一個內部函數,它就是異常中止你運行的程序.