在咱們的實際開發過程之中,經常會出現一些隱藏得很深的BUG,或者是一些機率性發生的BUG,一般這些BUG在咱們調試的過程當中不會出現很明顯的問題,可是若是咱們將其發佈,在用戶的各類運行環境下,這些程序可能就會露出馬腳了。那麼,如何讓咱們的程序更明顯的暴露出問題呢?這種狀況下,咱們通常都會使用 assert 斷言函數,這是C語言標準庫提供的一個函數,也就是說,它的使用與操做系統平臺,調試器種類無關。咱們只要學會了它的使用,即可一次使用,到處開花。ios
void assert(int expression);
assert宏的原型定義在 <assert.h>
中,其做用是先計算表達式expression的值爲假(即爲0),那麼它就先向stderr打印一條出錯信息,而後經過條用abort來終止程序;express
使用assert的缺點是,頻繁的調用會極大的影響程序的性能,增長額外的開銷。編程
下面實際使用一下 assert
函數
#include <assert.h> #include <iostream> // #include <cassert> using namespace std; int main() { cout << "====assert test====\n"; assert(true); //表達式爲真 assert(1 >= 2); //表達式爲假 return 0; }
在 VS Code 中運行(Ctrl + Alt + N)性能
出現異常單元測試
上面這個錯誤是很典型異常,能夠考慮用assert排查。測試
根據提示咱們很快就能定位到錯誤點,就在assert(1 >= 2)處;既然assert這麼便於定位出錯點,在工程中使用它就顯得頗有必要;但其也有必定的使用規則;spa
斷言語句不會永遠被執行,能夠屏蔽也能夠啓用,這就要求assert不論是在屏蔽仍是啓用狀態下都不能對咱們自己代碼有所影響.操作系統
那麼咱們通常在什麼狀況下使用斷言呢?調試
主要體如今如下幾個方面:
能夠在預計正常狀況下程序不會到達的地方放置斷言。(如assert(0);)
使用斷言測試方法的前置條件和後置條件;
固然咱們在使用斷言的過程當中會有一些咱們應該注意的事項和養成一些良好的習慣,如:
沒法直觀的判斷哪一個條件失敗:
assert(nOffset >= 0 && nOffset + nSize <= m_nInfomationSize);
只檢驗一個條件,比較直觀:
assert(nOffset >= 0); assert(nOffset + nSize <= m_nInfomationSize);
例如:
assert(i++ < 100)
錯誤點:這是由於若是出錯,好比在執行以前i=100,那麼這條語句就不會執行,那麼i++這條命令就沒有執行。
assert(i < 100) i++;
正確。
assert和後面的語句應該空一行,以造成邏輯和視覺上的一致性,也算是一種良好的編程習慣,讓編寫的代碼有一種視覺上的美感;
有的地方,assert不能代替條件過濾;
程序通常分爲Debug 版本和Release 版本,Debug 版本用於內部調試,Release 版本發行給用戶使用。斷言assert 是僅在Debug 版本起做用的宏,它用於檢查"不該該"發生的狀況。
int resetBufferSize(int nNewSize) { //功能:改變緩衝區大小, //參數:nNewSize 緩衝區新長度 //返回值:緩衝區當前長度 //說明:保持原信息內容不變 nNewSize<=0表示清除緩衝區 assert(nNewSize >= 0); assert(nNewSize <= MAX_BUFFER_SIZE); ... }
在咱們使用C語言/C++作工程項目時,若是咱們能在代碼中合理的使用assert,能使咱們建立更穩定、質量更好且不易於出錯的代碼;當須要在一個值爲false
時中斷當前操做的話就可使用斷言。
單元測試必須使用斷言;另外除了類型檢查和單元測試外,斷言還提供了一種肯定各類特性是否在程序中獲得維護的極好的方法;