從LLVM源碼學C++(四)

關鍵知識點:斷言linux

1 const Option OptTable::getOption(OptSpecifier Opt) const {
2   unsigned id = Opt.getID();
3   if (id == 0)
4     return Option(0, 0);
5   assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
6   return Option(&getInfo(id), this);
7 }

斷言:(轉)http://blog.csdn.net/szlanny/article/details/4267862程序員

斷言的應該是一種編程的常見技巧。我所應用的斷言有兩種,一種是動態斷言,即你們所熟知的C標準庫的assert()宏,一種是C++中的靜態斷言,即在編譯期間檢查。express

 

1)動態斷言:assert宏的原型定義在<assert.h>中,其做用是若是它的條件返回錯誤,則終止程序執行,原型定義:編程

[c-sharp]  view plain copy
 
  1. #include <assert.h>  
  2. void assert( int expression );  

 

assert的做用是先計算表達式 expression ,若是其值爲假(即爲0),那麼它先向stderr打印一條出錯信息,而後經過調用 abort 來終止程序運行。
你們要注意是,其中的表達式爲假時,會終止程序運行,包括我在內常常會寫錯代碼,斷言一個指針是否爲空,每每寫成了
assert(!p);其實應該寫成assert(p);
assert是運行期的判斷,而且會強制終止程序,通常要求只能用於debug版本中,是爲了儘量快的發現問題。尤爲在我所從事的電信軟件產品中,assert是要從release版本中去掉。因此通常開發會從新定義assert宏。this


2)靜態斷言,在新的C++標準中C++0x中,加了對靜態斷言的支持,引入了新的關鍵字static_assert來表示靜態斷言。使用靜態斷言,咱們能夠在程序的編譯時期檢測一些條件是否成立。但這個關鍵字太新了,沒有幾個編譯器是支持的(好像VC2008支持,我用VC不多,主要是在linux下C++編程)。因而可使用C++現有的模板特性來實現靜態斷言的功能。boost中也已有BOOST_STATIC_ASSERT宏的實現,有興趣的同窗能夠down下來仔細研究一下,它的斷言信息更豐富,下面爲個人簡單實現:spa

 

[c-sharp]  view plain copy
 
  1. // declare a tempalte class StaticAssert.  
  2. template <bool assertion> struct StaticAssert;  
  3.   
  4. // only partial specializate parameter's value is true.  
  5. template <> struct StaticAssert<true>   
  6. {  
  7.   enum { VALUE = 1 };  
  8. };  
  9.  
  10. #define STATIC_ASSERT(expression) (void)StaticAssert<expression>::VALUE   

 

原理是,先聲明一個模板類,但後面僅僅偏特化參數值爲true的類,而爲false的類則一個未定義的類,便是一個未完整的類型,編譯期間沒法找到StaticAssert<false>::VALUE類型。舉例以下:.net

 

[c-sharp]  view plain copy
 
  1. STATIC_ASSERT(4 == sizeof(long) ); //在 32bit機上OK  
  2. STATIC_ASSERT(4 == sizeof(long) ); //在 64bit機上NG,long爲8字節  

 

靜態斷言在編譯時進行處理,不會產生任何運行時刻空間和時間上的開銷,這就使得它比assert宏具備更好的效率。另外比較重要的一個特性是若是斷言失敗,它會產生有意義且充分的診斷信息,幫助程序員快速解決問題。debug

相關文章
相關標籤/搜索