簡介
C++11中引入了static_assert這個關(guān)鍵字,用來做編譯期間的斷言,因此叫做靜態(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編譯期間斷言,不生成目標(biāo)代碼,因此static_assert不會造成任何運行期性能損失。
范例
比如這段代碼中采用static_assert在編譯階段對相關(guān)的配置參數(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);
}
相關(guān)比較
我們知道,C++現(xiàn)有的標(biāo)準(zhǔn)中,就有assert、#error兩個設(shè)施,也是用來檢查錯誤的,還有一些第三方的靜態(tài)斷言實現(xiàn)。
assert是運行期斷言,它用來發(fā)現(xiàn)運行期間的錯誤,不能提前到編譯期發(fā)現(xiàn)錯誤,也不具有強制性,也談不上改善編譯信息的可讀性,既然是運行期檢查,對性能當(dāng)然是有影響的,所以經(jīng)常在發(fā)行版本中,assert都會被關(guān)掉;
#error可看做預(yù)編譯期斷言,甚至都算不上斷言,僅僅能在預(yù)編譯時顯示一個錯誤信息,它能做的不多,可以參與預(yù)編譯的條件檢查,由于它無法獲得編譯信息,當(dāng)然就做不了更進一步分析了。
那么,在stastic_assert提交到C++0x標(biāo)準(zhǔn)之前,為了彌補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