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

C 語言預定義巨集完整手冊:__FILE__、__LINE__、__func__ 等除錯利器

     編輯:關於C

前言

C 標準定義多個預定義巨集,在預處理階段自動展開為編譯時資訊。善用它們能打造專業級日誌、斷言、錯誤回報系統。本文完整整理 C99/C11 標準巨集用法與實戰範例。

標準預定義巨集表

巨集類型展開內容範例標準
__DATE__字串常數編譯日期 (Mmm dd yyyy)"Feb 12 1996"C89
__TIME__字串常數編譯時間 (hh:mm:ss)"23:59:01"C89
__FILE__字串常數當前原始檔完整路徑"/usr/src/main.c"C89
__LINE__整數常數當前行號42C89
__func__靜態字串變數當前函式名稱"main"C99
__FUNCTION__字串常數 (GCC 擴充)同 __func__"main"GCC
__STDC__整數常數1 表示符合 ISO C1C89
__STDC_VERSION__長整數常數C 標準版本 (yyyymmL)201710L (C18)C99
__STDC_HOSTED__整數常數1=宿主環境, 0=獨立環境1C99

實戰應用範例

1. 專業日誌巨集


#define LOG(fmt, ...) \
    fprintf(stderr, "[%s:%d %s] " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)

#define ASSERT(cond) \
    do { if (!(cond)) { \
        fprintf(stderr, "ASSERT FAILED: %s:%d %s: %s\n", \
                __FILE__, __LINE__, __func__, #cond); \
        abort(); \
    } } while(0)

2. 使用範例


void process_data(int *buf, int len) {
    ASSERT(buf != NULL);
    ASSERT(len > 0);
    
    LOG("Processing %d items", len);
    // ...
    if (error) LOG("Error code %d at index %d", err, i);
}

輸出範例


[main.c:42 process_data] Processing 100 items
[main.c:47 process_data] Error code -1 at index 5
ASSERT FAILED: main.c:38 process_data: buf != NULL

特殊行為說明

#line 指令影響


#line 100 "virtual.c"
printf("%s:%d\n", __FILE__, __LINE__);  // 輸出 virtual.c:100
// 下一行 __LINE__ 變為 101

#include 影響

進入標頭檔時 __FILE__/__LINE__ 切換為標頭檔資訊,返回主檔後恢復 (但 __LINE__ 會 +1)。

編譯器擴充巨集 (GCC/Clang/MSVC 常見)

巨集說明
__PRETTY_FUNCTION__函式完整簽名 (含類別、模板參數)
__COUNTER__遞增整數 (每次使用 +1),用於生成唯一識別碼
__TIMESTAMP__檔案最後修改時間
__BASE_FILE__主編譯檔案名稱 (非標頭檔)
__INCLUDE_LEVEL__標頭檔巢狀深度

條件編譯應用


// 僅在 C99 以上啟用特定功能
#if __STDC_VERSION__ >= 199901L
#define HAS_INLINE 1
#endif

// 僅在 GCC/Clang 使用擴充功能
#if defined(__GNUC__) || defined(__clang__)
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif

最佳實務:永遠使用 __func__ 而非 __FUNCTION__ (標準化)、巨集參數用 ##__VA_ARGS__ 支援零參數、斷言巨集用 do{...}while(0) 包裹 確保分號語法正確。這些細節決定了巨集在大型專案中的穩定性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved