分類: c/c++
2013-06-27 09:07
12541人閱讀收藏
舉報 assert
assert巨集的原型定義在
中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義:
#include
void assert( int expression );
assert的作用是現計算表示式
expression
,如果其值為假(即為
0),那麼它先向
stderr
列印一條出錯資訊,
然後通過呼叫 abort
來終止程式執行。
請看下面的程式清單badptr.c
:#include
#include
#include
int main( void )
[root@localhost error_process]# gcc badptr.c
[root@localhost error_process]# ./a.out
a.out: badptr.c:14: main: assertion `fp'' failed.
已放棄
使用assert
的缺點是,頻繁的呼叫會極大的影響程式的效能,增加額外的開銷。
在除錯結束後,可以通過在包含#include
的語句之前插入
#define ndebug
來禁用assert
呼叫,示例**如下:
#include
#define ndebug
#include
用法總結與注意事項:
1)在函式開始處檢驗傳入引數的合法性
如:int resetbuffersize(int nnewsize)
2)每個
assert
只檢驗乙個條件
,因為同時檢驗多個條件時
,如果斷言失敗
,無法直觀的判斷是哪個條件失敗
不好: assert(noffset>=0 && noffset+nsize<=m_ninfomationsize);
好: assert(noffset >= 0);
assert(noffset+nsize <= m_ninfomationsize);
3)不能使用改變環境的語句,因為
assert
只在debug
個生效,
如果這麼做
,會使用程式在真正執行時遇到問題
錯誤: assert(i++ < 100)
這是因為如果出錯,比如在執行之前i=100,
那麼這條語句就不會執行,那麼
i++這條命令就沒有執行。
正確: assert(i < 100)
i++;
4)assert和後面的語句應空一行
,以形成邏輯和視覺上的一致感
5)有的地方
,assert
不能代替條件過濾
文章出處:
摘自《高質量c/c++
程式設計指南》
page 41-42...
程式一般分為debug
版本和release
版本,debug
版本用於內部除錯,
release
版本發行給使用者使用。
斷言assert
是僅在debug
版本起作用的巨集,它用於檢查
「不應該
」發生的情況。示例
6-5
是乙個記憶體複製函式。在執行過程中,如果
assert
的引數為假,那麼程式就會中止(一般地還會出現提示對話,說明在什麼地方引發了
assert
)。void *memcpy(void *pvto, const void *pvfrom, size_t size)
示例6-5
複製不重疊的記憶體塊
assert 不是乙個倉促拼湊起來的巨集。為了不在程式的
debug
版本和release
版本引起差別,
assert
不應該產生任何***。所以
assert
不是函式,而是巨集。程式設計師可以把
assert
看成乙個在任何系統狀態下都可以安全使用的無害測試手段。
如果程式在 assert
處終止了,並不是說含有該
assert
的函式有錯誤,而是呼叫者出了差錯,
assert
可以幫助我們找到發生錯誤的原因。
很少有比跟蹤到程式的斷言,卻不知道該斷言的作用更讓人沮喪的事了。你化了很多時間,不是為了排除錯誤,而只是為了弄清楚這個錯誤到底是什麼。有的時候,程式設計師偶爾還會設計出有錯誤的斷言。所以如果搞不清楚斷言檢查的是什麼,就很難判斷錯誤是出現在程式中,還是出現在斷言中。幸運的是這個問題很好解決,只要加上清晰的注釋即可。這本是顯而易見的事情,可是很少有程式設計師這樣做。這好比乙個人在森林裡,看到樹上釘著一塊「危險」
的大牌子。但危險到底是什麼?樹要倒?有廢井?有野獸?除非告訴人們「危險
」是什麼,否則這個警告牌難以起到積極有效的作用。難以理解的斷言常常被程式設計師忽略,甚至被刪除。
【規則6-5-1
】使用斷言捕捉不應該發生的非法情況。不要混淆非法情況與錯誤情況之間的區別,後者是必然存在的並且是一定要作出處理的。
【規則6-5-2
】在函式的入口處,使用斷言檢查引數的有效性(合法性)。
【建議6-5-1
】在編寫函式時,要進行反覆的考查,並且自問:
「我打算做哪些假定?
」一旦確定了的假定,就要使用斷言對假定進行檢查。
【建議6-5-2
】一般教科書都鼓勵程式設計師們進行防錯設計,但要記住這種程式設計風格可能會隱瞞錯誤。當進行防錯設計時,如果
「不可能發生
」的事情的確發生了,則要使用斷言進行報警。
assert巨集中應該包含的元素:
判斷條件;輸出當前斷言失敗的位置(檔案、行數等);返回錯誤;終止程式...
幾種典型的assert
的寫法:
vc中的寫法:
#define assert(f) \
do \
while (0) \
#define _assert(expr) \
do while (0)
其他平台的寫法:
# define assert(x) ((x) || (dbg_printf("assertion failed ("__file__":%d): \"%s\"\n",__line__,#x), break_point(), false))
原**位址:
c assert 使用方法
assert巨集的原型定義在 中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義 include void assert int expression assert的作用是現計算表示式 expression 如果其值為假 即為 0 那麼它先向 stderr 列印一條出錯資訊,然後通過呼叫 a...
c assert 使用方法
assert巨集的原型定義在中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義 include void assert int expression assert的作用是現計算表示式 expression 如果其值為假 即為0 那麼它先向stderr列印一條出錯資訊,然後通過呼叫 abort...
C Assert 斷言機制原理以及使用方法
msdn原文如是說 evaluates an expression and,when the result is false,prints a diagnostic message and aborts the program.判斷乙個表示式,如果結果為假,輸出診斷訊息並中止程式。void asse...