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

C語言標準預定義宏:調試定位的「GPS定位系統」

     編輯:關於C語言

五大標準調試宏

宏名類型含義示例輸出
__FILE__字符串字面量當前源文件路徑"/home/user/project/main.c"
__LINE__整數常量當前行號42
__func__字符串字面量 (C99)當前函數名"calculate_sum"
__DATE__字符串字面量編譯日期"Jan 15 2025"
__TIME__字符串字面量編譯時間"14:30:00"

實戰:構建專業級日誌宏

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

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

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

編譯器擴展宏 (GCC/Clang/MSVC)

宏編譯器含義
__PRETTY_FUNCTION__GCC/Clang帶簽名的函數名 (模板/重載友好)
__FUNCTION__GCC/MSVC同__func__,非標準
__COUNTER__GCC/MSVC單調遞增整數,生成唯一標識符
__BASE_FILE__GCC主源文件 (非頭文件)
__INCLUDE_LEVEL__GCC頭文件嵌套深度

進階技巧:字符串化與拼接

// 字符串化 #
#define STR(x) #x
#define XSTR(x) STR(x)

// 拼接 ##
#define CONCAT(a, b) a##b
#define UNIQUE_NAME(base) CONCAT(base, __COUNTER__)

// 實際應用:自動註冊測試用例
#define TEST_CASE(name) \
    static void UNIQUE_NAME(test_)(); \
    struct UNIQUE_NAME(Registrar_) { \
        UNIQUE_NAME(Registrar_)() { \
            test_registry_add(XSTR(name), UNIQUE_NAME(test_)); \
        } \
    } UNIQUE_NAME(reg_); \
    static void UNIQUE_NAME(test_)()

// 使用
TEST_CASE("string_reverse") {
    ASSERT(strcmp(reverse("abc"), "cba") == 0);
}

調試構建最佳實踐

  1. 編譯選項:-g -O0 -DDEBUG -fno-omit-frame-pointer
  2. 斷言策略:NDEBUG控制assert(),自定義ASSERT釋構版保留
  3. 地址消毒器:-fsanitize=address,undefined 捕獲UB
  4. 靜態分析:clang-tidy, cppcheck, Coverity
  5. 棧追蹤:backtrace() + dladdr() 獲取運行時調用棧

常見誤區

  • __func__ 是變量:實為 static const char __func__[] = "name";,不能用sizeof(__func__)獲取長度 (需strlen)
  • __DATE__/__TIME__ 觸發重編譯:每次構建時間變,導致增量構建失效,發布版建議固定或移除
  • VC6不支持__func__:用__FUNCTION__或升級編譯器 (VS2013+ 完整支持C99)

總結

__FILE__, __LINE__, __func__ 組成了編譯期的「時空座標系」。善用它們構建日誌、斷言、測試註冊、錯誤上下文捕獲,能讓調試效率提升數量級。記住:好的日誌是事後除錯的時光機,好的斷言是運行時的守護神。

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