在c++中有時會用到類似於標頭檔案保護的技術,以便有選擇的執行除錯**。基本思想是,程式可以包含一些用於除錯的**,但是這些**只在開發程式的時候使用。當應用程式編寫完成準備發布時,要先遮蔽掉除錯**。這種方法用到了兩種預處理功能:assert和ndebug。
assert預處理巨集
assert是一種預處理巨集。所謂預處理巨集其實就是乙個預處理變數,它的行為有點類似於內聯函式。assert巨集使用乙個表示式作為它的條件:
assert(expr);
首先對expr求值,如果表示式為假,assert輸出資訊並終止程式的執行。如果表示式為真,assert什麼也不做。
assert巨集常用於檢查「不能發生」的條件。例如,乙個對輸入文字進行操作的程式可能要求所有給定單詞的長度都大於某個閥值。此時,程式可以包含一條如下所示的語句:
assert(word.size()>threshold)
ndebug預處理變數
assert的行為依賴於乙個名為ndebug的預處理變數的狀態。如果定義了ndebug,則assert什麼也不做。預設狀態下沒有定義ndebug,此時assert將執行執行時檢查。
我們可以使用乙個#define語句定義ndebug,從而關閉除錯狀態。
定義ndebug能避免檢查各種條件所需的執行時開銷,當然此時根本就不會執行執行時檢查。因此,assert應該僅用於驗證那些確實不可能發生的事。我們可以把assert當成除錯程式的一種輔助手段,但是不能用它代替真正的執行時邏輯檢查,也不能替代程式本身應該包含的錯誤檢查。
除了使用assert外,也可以使用ndebug編寫自己的條件除錯**。如果ndebug未定義,將執行#ifndef和#endif之間的**;如果定義了ndebug,這些**將被忽略。
void pring(const
int ia, size_t size)
c++編譯器除了定義了之外,預處理器還定義了另外4個對於除錯很有用的名字:
名字作用
__func__
當前除錯的函式名字
__file__
存放檔名的字串字面值
__line__
存放當前行號的整型字面值
__time__
存放檔案編譯時間的字串字面值
__date__
存放檔案編譯日期的字串字面值
如下面的例子:
if(word.size() < threshold)
cerr << "error: "
<< __file__
<< ": in function "
<< __func__
<< " at line "
<< __line__
<< endl
<< " compiled on "
<< __data__
<< " at "
<< __time__
<< endl;
c 除錯技巧
看書的時候,結合自己不足一年的程式設計經驗,寫出來的乙個還算是比較基礎的c 除錯經驗的總結。1 重現bug 要重現bug,首先採用與bug第一次出現時完全相同的輸入。注意不要只執行觸發操作,因為bug 可能是由整個操作序列產生的。當能一致地重現這個bug時,應嘗試找出觸發這個bug的最小序列 可以從...
c 除錯技巧
大家都知道,打斷點是最為大家所熟知的除錯技巧,但是除了打斷點,還有哪些除錯的技巧呢?system.diagnostics 這個命令空間裡有很多可供除錯的類庫。diagnostics這個單詞的意思是診斷,在軟體的世界裡就是診斷程式存在的問題,即除錯。下面為大家介紹這個類庫里幾個非常實用的方法,這幾個方...
C 除錯技巧總結
1 條件中斷 for inti 0 i 100 i 第一種方法 執行輸出要i等於50,當開始執行for迴圈時,直接將i的值改為49,然後在執行。第二種方法 對if i 50 斷點執行進行條件設定為 i 50,然後按f5直接到條件i為50,則進入輸出語句 或者設定命中次數,選擇中斷,條件命中次數等於4...