C++斷言與靜態斷言


  斷言是很早之前就有的東西了,只需要引入cassert頭文件即可使用。往往assert被用於檢查不可能發生的行為,來確保開發者在調試階段盡早發現“不可能”事件真的發生了,如果真的發生了,那么就表示代碼的邏輯存在問題。最好的一點就是,斷言只在Debug中生效,因此對於Release版本是沒有效率上的影響的。  

#include <iostream>
#include <cassert>
using namespace std;
 
int main() {
    int i = 22;
    assert(i != 22);
    system("pause");
    return 0;
}

  上面的代碼就表示,你確認在這里i一定不會等於22,如果事實上真的是22,那么程序就會無情地被abort,並報告出現問題的源文件和行號(使用了魔法常量__FILE__和__LINE__),有助於及時定位問題。

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

  所以,我們可以自己寫一個類似的宏來解決這個問題,我們希望在違反斷言時觸發斷點陷阱門中斷而不是調用abort,這樣,在違反斷言時程序會暫停下來,等待程序員來檢查當前的狀態有何異常。

  下面是一個Visual C++中的實現。

#include <iostream>
#include <cassert>
using namespace std;
 
#define _ASSERT(x) if (!(x)) __asm {int 3};
 
int main() {
    int i = 22;
    //assert(i != 22);
    _ASSERT(i != 22);
    system("pause");
    return 0;
}

  上面定義了一個宏,名字當然可以自己取,實際上做的一件事就是檢查斷言,然后如果斷言結果為false(0),那么就調用內聯匯編指令int 3陷入調試中斷。

  在2011年的C++標准中出現了靜態斷言(static_assert)的語法,所謂靜態斷言,就是在編譯時就能夠進行檢查的斷言,static_assert是C++的標准語法,不需要引用頭文件。靜態斷言的另一個好處是,可以自定義違反斷言時的編譯錯誤信息。

#include <iostream>
using namespace std;
 
int main() {
    const int i = 22;
    static_assert(i != 22, "i equals to 22");
    system("pause");
    return 0;
}

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

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM