<assert.h> 僅提供 assert 巨集,用於在關鍵處檢查斷言。斷言失敗時輸出錯誤訊息至標準錯誤流並異常終止程式(呼叫 abort())。
範例:
#include <assert.h>
assert(0 <= i && i < sizeof(a)/sizeof(a[0]));
透過定義 NDEBUG 巨集可控制斷言啟用/停用:
assert 展開為活動形式,檢查條件,失敗時輸出檔案、行號、條件文本並 abort()。assert 展開為 ((void)0),零開銷。可在同一檔案中多次切換:
#define NDEBUG
#include <assert.h> // 此後斷言關閉
#undef NDEBUG
#include <assert.h> // 此後斷言開啟
框架:
#undef assert
#ifdef NDEBUG
#define assert(expr) ((void)0)
#else
void __bad_assertion(const char *msg);
#define __str(x) #x
#define __xstr(x) __str(x)
#define assert(expr) ((expr) ? (void)0 : \
__bad_assertion("Assertion \"" #expr "\" failed, file " __xstr(__FILE__) ", line " __xstr(__LINE__) "\n"))
#endif
關鍵技巧:
__FILE__、__LINE__ 內建巨集獲取位置。__LINE__ 為數字常數,需雙層字串化(__str/__xstr)轉為字串字面量。? 確保宏展開為 void 型別表達式,可用於任何語句位置。fprintf 等庫函式,避免未包含 <stdio.h> 時編譯錯誤;改呼叫隱藏函式 __bad_assertion。#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
void __bad_assertion(const char *mess) {
fputs(mess, stderr);
abort();
}
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *fp = fopen("test.txt", "w");
assert(fp); // 成功
fclose(fp);
fp = fopen("noexit.txt", "r"); // 失敗,fp == NULL
assert(fp); // 觸發斷言失敗,程式終止
return 0; // 不會執行到此
}
assert(nNewSize >= 0);assert(nOffset >= 0); assert(nOffset+nSize <= m_nInfomationSize);assert(i++ < 100); 錯誤(Release 下 i 不增),應寫 assert(i < 100); i++;