改進的C++ Builder assert()

來源:互聯網
上載者:User

http://bdn.borland.com/article/0,1410,28432,00.html
  摘要:assert()調用允許你測試代碼中的問題,但它有些局限。本文詳述了一個改進的assert調用。
  改進的C++ Builder assert()
   做為良好編程的一部分,您代碼中的斷言是監視正在發生了什麼的一種簡捷的途徑。本文討論給assert()增加靈活性,使其變得更有用。
  斷言的一些背景
   多年來,我一直使用assert()管理代碼。
   assert(int test)
   這個函數獲得test,斷言test結果為真——如果為真,什麼也不做,否則產生一個警告,允許您的程式方便地檢測錯誤。assert()的好處是它也是一個宏,如果你#define NDEBUG,這些宏從您的代碼消失,什麼也不留下。
   在檢查代碼很有用的同時,assert()自身也有一些問題:
  失敗的斷言預設是跳出程式,一個警告出現測試就結束。
  在每次到達時,assert()都要檢查,這使得在迴圈中難以使用。
  很難檢查代碼,因為assert()通常調用abort(),忽略斷言繼續調試就不可能。
  ASSERTING()
   當然,這些問題正是本文要解決的。通過修改assert(),我們得到驗證代碼更健壯更有用的方式。結果是一個我稱之為ASSERTING()的宏包,即和代碼脫離,又區別於assert(). 它包含在例子代碼的assert2.cpp/.dfm/.h檔案中:
   ASSERTING(int test,char *errorMessage)
  
   和正常的assert()一樣,NDEBUG決定這代碼是否被實際建立。它還添加了一個解釋資訊以有助於理解錯誤。
   標頭檔的宏表明它應該如何被處理。如果NDEBUG沒有被定義,在每個ASSERTING()調用時下列代碼將被展開。
   #define ASSERTING(test,msg)
   {
   if (!(test))
   {
   static int callIt=1;
   if (callIt)
   {
   if (HandleAsserting(#test,#msg,__FILE__,__LINE__,&callIt))
   { _asm { int 3 } }
   }
   }
   }
  該宏使用一個靜態變數,來決定調用是否繼續。我們的子函數HandleAsserting()可以關閉這個靜態變數,允許我們禁用這個位置以後的測試(例如,在一個迴圈中第一次失敗後)。子函數返回True執行彙編調用'int 3',在斷言後中斷到調試器。
  三個選項
  
   由於這些特色,HandleAsserting()調用有三個選項:
  
  設定靜態標誌為0,阻止以後的測試,“解僱”斷言。
  返回true,中斷到調試器。
  返回false,繼續執行。
   下面是一個簡單的non-VCL實現,在assert2.cpp檔案結尾有(被注釋掉的):
  int HandleAsserting(char *testStr,char *msgStr,char *fileStr,int line,int *callFlag)
   {
   // assert message & and return flag regarding aborting:
   // callFlag set if repeating forbidden
   static char s_text[199]=""; // don't assign dynamically in
   // case of 'out of memory' error
   wsprintf(s_text,"FAILED: %srn"
   "Error: ( %s )rn"
   "File '%s', Line %drn"
   "Abort execution, allow assert Retry, or Ignore in future?",
   msgStr,testStr,fileStr,line);
   switch ( ::MessageBox(NULL,s_text,"ASSERTION ERROR",MB_ABORTRETRYIGNORE) )
   {
   case IDIGNORE: // prevent calling again - turn off flag
   *callFlag=0; // never call again
  
  break;
   case IDABORT: // return flag and break
   return 1; // abort/break
   }
   return 0;
   }
  這個函數調用MessageBox()去顯示宣告失敗,使用Abort/Retry/Ignore按鈕來獲得三種可能情況。
  鑒於這比較有用,我們讓C++ Builder 用我們的調用,當然,可以根據我們的需要定製VCL Form。本文提供的原始碼包含一個TRichEdit控制項,斷言錯誤資訊的格式很鮮明。示範程式允許您解僱斷言,實驗不同的選項。一個關於VCL版本的告誡是——在其他表單構造時避免用它。
  結束
   斷言是一種保證代碼按您期望的那樣做,不增加冗餘代碼的唾手可得的方式。本文提供了一些附加的你會發現比較有用的特色,擴充了使用斷言的機會。
   (翻譯 01soft)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.