assert使用總結

2021-05-22 00:35:51 字數 2503 閱讀 2129

assert expression1;

assert expression1:expression2;

如果expression1為true,則不丟擲錯誤,程式正常執行,expression2也不會執行。

如果expression1為false,則丟擲異常,程式中斷跳出,expression2執行。

一般來說,不要在expression1、expression2中使用函式的返回值;

不要將其使用在public函式中檢查輸入引數,但可以用於private函式中檢測輸入引數。

個人的一點理解:使用assert只是為了幫助我們除錯程式,因此使用assert所遵循的原則就是「不能因為有了assert的存在而使程式的結構發生任何的改變」,說白了就是「如果把assert部分刪除了,程式依然不會有任何的問題,只不過不能幫助我們檢查出一些錯誤來了」,因此使用assert的時候不應該在表示式中使用函式,因為一旦把這句assert語句刪除後,程式的結構就改變了,這不符合上述提到的原則!

程式一般分為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))

1)在函式開始處檢驗傳入引數的合法性

如:int cbufferpool::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)

正確: assert(i < 100)

i++;

4)assert和後面的語句應空一行,以形成邏輯和視覺上的一致感

5)有的地方,assert不能代替條件過濾,如:

int cdecodebuffer::getintvalue(int noffset, int nsize) const

return nreturn;

}

assert用法總結

assert巨集的原型定義在中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義 include void assert int expression assert的作用是現計算表示式 expression 如果其值為假 即為0 那麼它先向stderr列印一條出錯資訊,然後通過呼叫 abort...

assert用法總結

assert巨集的原型定義在中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義 include void assert int expression assert的作用是現計算表示式 expression 如果其值為假 即為0 那麼它先向stderr列印一條出錯資訊,然後通過呼叫 abort...

assert用法總結

assert巨集的原型定義在中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義 assert的作用是現計算表示式 expression 如果其值為假 即為0 那麼它先向stderr列印一條出錯資訊,然後通過呼叫 abort 來終止程式執行。請看下面的程式清單badptr.c root loc...