首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C標準庫assert.h斷言宏完整指南

     編輯:關於C

assert.h 診斷宏深度解析

<assert.h> 是 C 標準函數庫中極具特色的標頭檔,提供 assert() 宏用於程式除錯。其獨特之處在於可重複引入並根據 NDEBUG 宏產生不同行為。

assert() 宏運作機制

void assert(int expression);
  • 表達式非零:不執行任何操作
  • 表達式為零:列印診斷訊息並呼叫 abort() 終止程式

診斷訊息包含內容

  1. 原始碼檔名(__FILE__ 宏)
  2. 行號(__LINE__ 宏)
  3. 函數名(__func__,C99 新增)
  4. 求值為零的表達式本身

輸出目標區分

程式類型診斷輸出目標
控制台程式stderr 標準錯誤裝置
視窗程式Windows MessageBox 對話框

停用 assert() 的方法

無需修改原始碼即可屏蔽所有斷言:

  • 編譯器命令列定義:-DNDEBUG(GCC/Clang)或 /DNDEBUG(MSVC)
  • 原始碼中 #include <assert.h> 前定義:#define NDEBUG

重要:被停用的 assert() 甚至不會對參數表達式求值,因此參數不可包含副作用(如 assert(x++ > 0) 會導致釋出版本邏輯錯誤)。

實戰範例

基本用法:檔案開啟檢查

#include <stdio.h>
#include <assert.h>

int main(void) {
    FILE *fd = fopen("/home/user/file.txt", "r");
    assert(fd);  // 若 fd 為 NULL,程式終止並輸出診斷資訊
    fclose(fd);
    return 0;
}

NDEBUG 影響示範

// 未定義 NDEBUG
#include <stdio.h>
#include <assert.h>

int main() {
    printf("1 ok hello\n");
    assert(1 == 4);  // 觸發斷言失敗
    printf("2 ok exit\n");  // 不會執行
    return 0;
}
/* 輸出:
1 ok hello
assert_h_ex.c:7: main: Assertion `1==4' failed.
Aborted
*/
// 定義 NDEBUG
#include <stdio.h>
#define NDEBUG
#include <assert.h>

int main() {
    printf("1 ok hello\n");
    assert(1 == 4);  // 被忽略
    printf("2 ok exit\n");  // 正常執行
    return 0;
}
/* 輸出:
1 ok hello
2 ok exit
*/

assert() 內部實作原理

#define assert(test) if(!(test)) \
    fprintf(stderr, "Assertion failed: %s, file %s, line %d\n", \
            #test, __FILE__, __LINE__), \
    abort()

利用字串化運算子 # 將表達式轉為字串,配合 __FILE__、__LINE__ 定義宏。

自訂斷言宏範例

#define Assert(test) if(!(test)) \
    fprintf(stderr, "Assertion failed: %s, file %s, line %d\n", \
            #test, __FILE__, __LINE__), \
    abort()

行為與標準 assert() 類似,但不受 NDEBUG 控制,適合需永久保留的關鍵檢查。

最佳實務建議

  1. 僅用於除錯:檢查「不應發生」的邏輯錯誤,非預期錯誤處理
  2. 避免副作用:斷言條件勿包含賦值、函數呼叫等有副作用操作
  3. 釋出版本自動移除:透過 NDEBUG 確保零效能負擔
  4. 關鍵檢查另行處理:生產環境必須檢查的條件(如參數驗證)應用 if 而非 assert
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved