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

C 語言預定義宏完全指南:__FILE__、__LINE__、__func__ 等調試利器

     編輯:關於C語言

標準預定義宏 (C89/C99/C11)

宏類型含義標準
__DATE__字符串常量編譯日期 "Mmm dd yyyy" (如 "Feb 12 1996")C89
__TIME__字符串常量編譯時間 "hh:mm:ss"C89
__FILE__字符串常量當前源文件路徑C89
__LINE__整數常量當前行號C89
__func__字符串變量當前函數名 (靜態存儲)C99
__STDC__整數常量1 表示符合標準 CC89
__STDC_VERSION__長整數常量版本號 yyyymmL (199409L= C90, 199901L= C99)C99
__STDC_HOSTED__整數常量1=託管環境(完整庫), 0=自由環境C99

GCC/Clang 常用擴展宏

宏含義
__FUNCTION____func__ 同義詞 (GCC 早期引入)
__PRETTY_FUNCTION__函數簽名 (含參數、模板、類名,C++ 極其有用)
__BASE_FILE__主源文件名 (遞歸 #include 時頂層文件)
__COUNTER__遞增整數 (每次使用 +1,生成唯一標識)
__TIMESTAMP__文件最後修改時間
__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__GCC 版本號
__clang__, __clang_major__...Clang 版本號
__cplusplusC++ 版本 (199711L, 201103L, 201402L, 201703L, 202002L)

調試與日誌最佳實踐


// 通用斷言宏
#define ASSERT(cond) \
    do { if (!(cond)) { \
        fprintf(stderr, "ASSERT failed: %s, %s:%d, %s\n", \
                #cond, __FILE__, __LINE__, __func__); \
        abort(); \
    } } while(0)

// 格式化日誌宏
#define LOG(fmt, ...) \
    fprintf(stderr, "[%s:%d %s] " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)

// 使用示例
void process(int fd) {
    LOG("start fd=%d", fd);
    ASSERT(fd >= 0);
    // ...
}

#line 指令交互


#line 100 "virtual.c"  // 修改 __LINE__=100, __FILE__="virtual.c"
int x = 1;            // __LINE__ 為 101
#line 200             // 僅修改行號
int y = 2;            // __LINE__ 為 201

常用於代碼生成工具(lex/yacc、protobuf、Qt MOC)保持錯誤定位準確。

注意事項

  • __func__ 是變量而非宏,不能用 #ifdef 判斷,但可作為字符串使用。
  • __STDC__ 在 GCC 非標準模式 (-traditional-cpp) 下可能未定義,檢查用 #if __STDC__ 而非 #ifdef。
  • C++ 中 __cplusplus 是檢測標準版本的唯一可靠宏。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved