ssert是只有定義了DEBUG才起作用的宏,如果其參數(shù)的計算結果為假,就中止調用程序的執(zhí)行。
assert餅不是一個倉促拼湊起來的宏,為了不在程序的release和debug版本之間引起重要的差別,需要對其進行仔細的定義。宏assert不應該弄亂內存,不應該對未初始化的數(shù)據(jù)進行初始化,即它不應該產(chǎn)生其他副作用。正因為要求程序的debug版本和release版本行為完全相同,所以才不把assert作為函數(shù),而把它做成宏。如果把assert做成函數(shù)的話,其調用就會引起不期望的內存或代碼的兌換。要記住,使用assert的程序員是把它看成一個在任意系統(tǒng)狀態(tài)下都可以安全使用的無害檢測手段。
在同錯誤進行斗爭時,每一點幫助都會有助于錯誤的發(fā)現(xiàn)。我們?yōu)槭裁匆切┳约簭膩矶加貌恢撵`活性呢?
#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失敗時,他就會使用預處理程序根據(jù)宏_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();
}
在執(zhí)行abort之前,需要調用fflush將所有的緩沖輸出寫到標準輸出設備stdout上。同樣,如果stdout 和stderr 都將指向同一設備,fflush stdout仍然要放在fflush stderr之前,以確保只有在所有的輸出都送到了stdout之后,fprintf才顯示相應的錯誤信息。
不管斷言宏最終是用什么樣子方法定義的,都要使用它來對傳遞給相應函數(shù)的參數(shù)進行確認。如果在函數(shù)的每個調用點都對其進行參數(shù)進行檢查,錯誤很快就會被發(fā)現(xiàn)。斷言宏最好作用是使用戶在錯誤發(fā)生時,就可以自動地把他們檢查出來。
此外關于斷言,也有兩篇不錯的文章
http://blog.csdn.net/donghai51arm/archive/2009/11/28/4897004.aspx
http://dev.firnow.com/course/3_program/c++/cppsl/200861/118777.html