下面是一個比較簡單的下面是一個比較簡單的TRACE和ASSERT的WIN32實現:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
#define ASSERT(expr) /
do { /
if (!(expr) && /
(1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, NULL, #expr))) /
__asm { int 3 }; /
} while (0)
#define TRACE(expr) /
_CrtDbgReport(_CRT_WARN, __FILE__, __LINE__, NULL, expr)
它們調用的都是_CrtDbgReport函數,其原型如下:
_CRTIMP int __cdecl _CrtDbgReport(
int nRptType,
const char * szFile,
int nLine,
const char * szModule,
const char * szFormat,
...
);
_CrtDbgReport的第一個參數表示報告消息的類型,有下面三種類型:
#define _CRT_WARN 0
#define _CRT_ERROR 1
#define _CRT_ASSERT 2
_CrtDbgReport函數的實現大體上是先拼接好報告消息,然後根據消息的類型將消息發往合適的地方,具體如下:
首先判斷_CrtDbgMode[nRptType]的值,通過觀察,知道
_CrtDbgMode[0] = 2;
_CrtDbgMode[1] = 4;
_CrtDbgMode[2] = 4;
系統定義了下面的宏來說明這些報告消息發往何處,
#define _CRTDBG_MODE_FILE 0x1
#define _CRTDBG_MODE_DEBUG 0x2
#define _CRTDBG_MODE_WNDW 0x4
再通過源代碼和MSDN的幫助,終於弄清楚了消息的去處:
如果_CrtDbgMode[nRptType]是_CRTDBG_MODE_DEBUG,則調用OutputDebugString將報告消息發送給調試器。
如果_CrtDbgMode[nRptType]是_CRTDBG_MODE_WNDW,則彈出一個具有終止、重試、忽略三個按鈕的對話框。
讓我們回頭來看看ASSERT宏,顯然,如果expr非零,則ASSERT成功,直接退出while循環,根本不會執行_CrtDbgReport;如果expr爲0,則執行_CrtDbgReport,如果用戶選擇終止,則應用程序立即終止;若選擇重試,則_CrtDbgReport返回1,程序會執行下面的彙編語句,這個語句會使得程序中斷,就跟你設置了斷點一樣;若用戶選擇忽略,則程序繼續執行。順便說明一下,#expr表示將expr轉換爲字符串,比如,若ASSERT(0==i),則#expr爲“0==i“。
如果_CrtDbgMode[nRptType]是_CRTDBG_MODE_FILE,則將報告信息寫入_CrtDbgFile[nRptType]表示的文件中。
TRACE宏的非WIN32實現很簡單,就是調用printf直接輸出報告消息。