淺談TRACE、ASSERT宏的一種實現

下面是一個比較簡單的下面是一個比較簡單的TRACEASSERTWIN32實現:<?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;如果expr0,則執行_CrtDbgReport,如果用戶選擇終止,則應用程序立即終止;若選擇重試,則_CrtDbgReport返回1,程序會執行下面的彙編語句,這個語句會使得程序中斷,就跟你設置了斷點一樣;若用戶選擇忽略,則程序繼續執行。順便說明一下,#expr表示將expr轉換爲字符串,比如,若ASSERT(0==i),則#expr爲“0==i“。

如果_CrtDbgMode[nRptType]_CRTDBG_MODE_FILE,則將報告信息寫入_CrtDbgFile[nRptType]表示的文件中。


TRACE
宏的非WIN32實現很簡單,就是調用printf直接輸出報告消息。

發佈了38 篇原創文章 · 獲贊 1 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章