一、assert宏的原型定義在<assert.h>中,其做用是若是它的條件返回錯誤,則終止程序執行,原型定義:
#include <assert.h>
void assert( int expression );程序員
assert的做用是現計算表達式 expression ,若是其值爲假(即爲0),那麼它先向stderr打印一條出錯信息,而後經過調用 abort 來終止程序運行。express
二、使用assert的缺點是,頻繁的調用會極大的影響程序的性能,增長額外的開銷。在調試結束後,能夠經過在包含#include <assert.h>的語句以前插入 #define NDEBUG 來禁用assert調用,示例代碼以下:
#include <stdio.h>
#define NDEBUG
#include <assert.h>編程
三、一些建議:函數
3.一、使用斷言捕捉不該該發生的非法狀況。不要混淆非法狀況與錯誤狀況之間的區別,後者是必然存在的而且是必定要做出處理的。
3.二、在函數的入口處,使用斷言檢查參數的有效性(合法性)。
3.三、在編寫函數時,要進行反覆的考查,而且自問:「我打算作哪些假定?」一旦肯定了的假定,就要使用斷言對假定進行檢查。
3.四、通常教科書都鼓勵程序員們進行防錯設計,但要記住這種編程風格可能會隱瞞錯誤。當進行防錯設計時,若是「不可能發生」的事情的確發生了,則要使用斷言進行報警。性能
四、一個例子:設計
char * clone_string(const char * source)調試
{內存
char * result;原型
assert(source != NULL);string
result = (char *)malloc(strlen(source) + 1);
if (result != NULL)
{
strcpy(result, source);
assert(strcmp(result, source) == 0);
}
return result;
}
注意到我對source是否爲NULL是用assert檢查的,但對result是否是爲NULL是用if語句判斷的,這是由於在調用代碼正確的狀況下source必然不爲NULL,若是斷言失敗,說明調用代碼中有錯誤,須要修改;但result做爲malloc的返回值則不必定,在malloc代碼無誤的狀況下仍然可能返回NULL——當內存塊不足時。最後又用assert對strcpy的結果進行檢查,由於只要代碼正確,不管什麼狀況strcpy應該正常完成複製,它沒有malloc那種異常狀況存在。