C 斷言與靜態斷言 1

2021-09-24 03:39:07 字數 1295 閱讀 3603

c++斷言與靜態斷言

斷言是很早之前就有的東西了,只需要引入cassert標頭檔案即可使用。往往assert被用於檢查不可能發生的行為,來確保開發者在除錯階段盡早發現「不可能」事件真的發生了,如果真的發生了,那麼就表示**的邏輯存在問題。最好的一點就是,斷言只在debug中生效,因此對於release版本是沒有效率上的影響的。  

#include #include using namespace std;

int main()

上面的**就表示,你確認在這裡i一定不會等於22,如果事實上真的是22,那麼程式就會無情地被abort,並報告出現問題的原始檔和行號(使用了魔法常量__file__和__line__),有助於及時定位問題。

斷言有乙個問題,就是一定會abort,強制整個程式退出而導致除錯也無法繼續進行,就像上圖這樣,出現問題後,我們知道了出現問題的行號,但是我們需要手動在該行的上面設定斷點,重新開始除錯才能夠檢查到發生問題時各個變數的狀態。而且,有時問題不是那麼容易重現,於是就可能出現沒法重現錯誤再檢查狀態的問題。

所以,我們可以自己寫乙個類似的巨集來解決這個問題,我們希望在違反斷言時觸發斷點陷阱門中斷而不是呼叫abort,這樣,在違反斷言時程式會暫停下來,等待程式設計師來檢查當前的狀態有何異常。

下面是乙個visual c++中的實現。

#include #include using namespace std; #define _assert(x) if (!(x)) __asm ; int main()

上面定義了乙個巨集,名字當然可以自己取,實際上做的一件事就是檢查斷言,然後如果斷言結果為false(0),那麼就呼叫內聯彙編指令int 3陷入除錯中斷。

在2023年的c++標準**現了靜態斷言(static_assert)的語法,所謂靜態斷言,就是在編譯時就能夠進行檢查的斷言,static_assert是c++的標準語法,不需要引用標頭檔案。靜態斷言的另乙個好處是,可以自定義違反斷言時的編譯錯誤資訊。

#include using namespace std;

int main()

這個**,將無法通過編譯,因為i的值違反了靜態斷言。

靜態斷言的限制是,斷言本身必須是常量表示式,如果這樣的i不是常量,靜態斷言是不符合語法的。

文章**;

原 C斷言 靜態斷言

關於斷言,可以作為一種很強大的除錯方式或者程式執行時的錯誤診斷 但是斷言也不是適合於各種地方,伺服器軟體和嵌入式程式一般不適用,斷言會強制中斷正在執行的程式,對於伺服器等程式來說,將會是乙個災難。加上,斷言會加劇cpu 的負載,其中會呼叫一些函式。作為除錯時使用斷言是個不錯的選擇 一般斷言 ifnd...

C 11 14執行時斷言與靜態斷言

標頭檔案 include 中的assert是執行時斷言,即當程式執行到assert處並該函式的形參計算出來為false。程式會出現報錯並退出。如果程式不執行到assert函式處是不會報錯的。而靜態斷言指的是在編譯階段就進行報錯。靜態斷言的實現 如下 define assert static e do...

C 11 靜態斷言static assert

一 assert 在c 中,或中提供了assert巨集 執行期斷言 可以定義ndebug來禁用assert巨集。二 static asser c 11 靜態斷言static assert,編譯期斷言。static assert 常量表示式,提示字串 兩個引數,乙個是斷言表示式,由於是在編譯期間,所以...