自己實現的assert(斷言)程式

來源:互聯網
上載者:User

自己實現的asset(斷言)程式

1、概況

       很多教科書都叫程式員在編程的時候要進行防錯設計,而實際上這也是必要的。防錯設計能有效捕捉到程式運行時出現的非法和錯誤狀態,這樣,程式員可以很快的定位錯誤發送的地方以便進一步處理。很難想象到了一定規模的系統沒有防錯設計是多麼的可怕。有一句很經典的話:不知道不可怕,可怕的是不知道自己不知道。這句話用在這裡一樣經典:程式出錯不可怕,可怕的是不知道出錯了。

       防錯設計有很多種,比如記錄log檔案、對話方塊出錯提示等等。今天我要說的防錯設計是assert(斷言)。

2、assert(斷言)

       程式一般分為Debug 版本和Release 版本,Debug 版本用於內部調試,Release 版本發行給使用者使用。斷言assert 是僅在Debug 版本起作用的宏,它用於監測“不應該”發生的情況。為了不在程式的Debug 版本和Release 版本引起差別,assert 不應該產生任何副作用。所以assert 不是函數,而是宏。程式員可以把assert看成一個在任何系統狀態下都可以安全使用的無害測試手段。

2.1 各種類型的斷言

       C和C++都給我們提供了斷言:

◆ANSI C斷言:assert函數。

◆C運行時刻函數庫斷言:_ASSERT宏和_ASSERTE宏。

◆MFC庫的斷言:ASSERT 宏、_ASSERT 宏、VERIFY宏、ASSERT_VALID宏、ASSERT_KINDOF宏、ASSERT_POINTER宏和ASSERT_NULL_OR_POINTER宏。

◆ATL斷言:ATLASSERT 

      今天我詳細介紹這些斷言的使用方法,大家可以自己去網上查詢。

2.2 斷言的使用

      斷言是用來監測錯誤的,不是用來糾正錯誤。我們應該帶著防禦性、檢測性地使用斷言。比如函數參數的合法性(有效性)檢查,API函數調用傳回值的正確性檢查等。

3、自己實現的“斷言”

       筆者在使用斷言的時候,更願意自己定製斷言的形式,比如可以定製錯誤資訊是顯示在標準的輸出螢幕上(類似命令列的視窗),還是顯示在彈出對話方塊中;可以定製錯誤資訊包括的內容:出錯的源碼檔案名稱,出錯的行號,出錯的代碼,出錯的提示資訊等等。以下這個宏就是筆者自己定製的一個斷言宏。有不妥之處,忘大家指教。

  1. /*
  2. * MyVerify.h
  3. * 自己實現的斷言宏——MYVERIFY
  4. * 2008.10.30
  5. * Kaoya
  6. */
  7. #ifndef __MYVERIFY_H__
  8. #define __MYVERIFY_H__
  9. #pragma comment( lib, "USER32" )
  10. #include <crtdbg.h>
  11. #ifdef _DEBUG
  12. #define MYVERIFY(a) if (!(a)) PrintError(#a,__FILE__,__LINE__,GetLastError())
  13. #else
  14. #define MYVERIFY(a)
  15. #endif
  16. __inline void PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum)
  17. {
  18.   LPSTR lpBuffer;
  19.   char errbuf[256];
  20.   char modulename[MAX_PATH];
  21.   DWORD numread;
  22.   
  23.   FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER 
  24.     | FORMAT_MESSAGE_FROM_SYSTEM,
  25.     NULL,
  26.     errnum,
  27.     LANG_NEUTRAL,
  28.     (LPTSTR)&lpBuffer,
  29.     0,
  30.     NULL );
  31.   
  32.   GetModuleFileName(NULL, modulename, MAX_PATH);
  33.   wsprintf(errbuf, "/n%s occur failed at line %d in %s:/n/n"
  34.     "    %s/n/nReason: %s/n", modulename, lineno, filename, linedesc, lpBuffer);
  35.   
  36. #ifndef _WINDOWS
  37.   WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE );
  38.   Sleep(3000);
  39. #else
  40.   MessageBox(GetActiveWindow(), errbuf, modulename, MB_ICONWARNING|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
  41. #endif
  42.   
  43.   exit(EXIT_FAILURE);
  44. }
  45. #endif//__MYVERIFY_H__

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.