簡介
C++11中引入了static_assert這個關鍵字,用來做編譯期間的斷言戴卜,因此叫做靜態(tài)斷言逾条。
其語法很簡單:static_assert(常量表達式,提示字符串)投剥。
如果第一個參數(shù)常量表達式的值為真(true或者非零值)师脂,那么static_assert不做任何事情,就像它不存在一樣薇缅,否則會產(chǎn)生一條編譯錯誤危彩,錯誤位置就是該static_assert語句所在行,錯誤提示就是第二個參數(shù)提示字符串泳桦。
說明
使用static_assert汤徽,我們可以在編譯期間發(fā)現(xiàn)更多的錯誤,用編譯器來強制保證一些契約灸撰,并幫助我們改善編譯信息的可讀性谒府,尤其是用于模板的時候。
static_assert可以用在全局作用域中浮毯,命名空間中完疫,類作用域中,函數(shù)作用域中债蓝,幾乎可以不受限制的使用壳鹤。
編譯器在遇到一個static_assert語句時,通常立刻將其第一個參數(shù)作為常量表達式進行演算饰迹,但如果該常量表達式依賴于某些模板參數(shù)芳誓,則延遲到模板實例化時再進行演算,這就讓檢查模板參數(shù)成為了可能啊鸭。
性能方面锹淌,由于是static_assert編譯期間斷言,不生成目標代碼赠制,因此static_assert不會造成任何運行期性能損失赂摆。
范例
比如這段代碼中采用static_assert在編譯階段對相關的配置參數(shù)進行檢查。
bool operator==(const Http2PingFields& a, const Http2PingFields& b) {
? static_assert((sizeof a.opaque_bytes) == Http2PingFields::EncodedSize(),
? ? ? ? ? ? ? ? "Why not the same size?");
? return 0 ==
? ? ? ? std::memcmp(a.opaque_bytes, b.opaque_bytes, sizeof a.opaque_bytes);
}
相關比較
我們知道钟些,C++現(xiàn)有的標準中烟号,就有assert、#error兩個設施政恍,也是用來檢查錯誤的汪拥,還有一些第三方的靜態(tài)斷言實現(xiàn)。
assert是運行期斷言抚垃,它用來發(fā)現(xiàn)運行期間的錯誤,不能提前到編譯期發(fā)現(xiàn)錯誤,也不具有強制性鹤树,也談不上改善編譯信息的可讀性铣焊,既然是運行期檢查,對性能當然是有影響的罕伯,所以經(jīng)常在發(fā)行版本中曲伊,assert都會被關掉;
#error可看做預編譯期斷言追他,甚至都算不上斷言坟募,僅僅能在預編譯時顯示一個錯誤信息,它能做的不多邑狸,可以參與預編譯的條件檢查懈糯,由于它無法獲得編譯信息,當然就做不了更進一步分析了单雾。
那么赚哗,在stastic_assert提交到C++0x標準之前,為了彌補assert和#error的不足硅堆,出現(xiàn)了一些第三方解決方案屿储,可以作編譯期的靜態(tài)檢查,例如BOOST_STATIC_ASSERT和LOKI_STATIC_CHECK渐逃,但由于它們都是利用了一些編譯器的隱晦特性實現(xiàn)的trick够掠,可移植性、簡便性都不是太好茄菊,還會降低編譯速度疯潭,而且功能也不夠完善,例如BOOST_STATIC_ASSERT就不能定義錯誤提示文字买羞,而LOKI_STATIC_CHECK則要求提示文字滿足C++類型定義的語法袁勺。
參考
https://www.cnblogs.com/lvdongjie/p/4489835.html