c assert 使用方法

2021-07-05 00:25:16 字數 3333 閱讀 2301



分類: 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...