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

C 語言內置宏實戰:__FILE__、__LINE__ 實現精準調試定位

     編輯:關於C語言

編譯器如何知道錯誤在哪一行?內置宏揭秘

當編譯器報錯 test.c:13: error: ... 時,它是如何獲取文件名和行號的?答案就是 C 語言標準定義的內置預定義宏。這些宏無需 #define,直接可用,在預處理階段展開為當前編譯上下文的常量值。

常用內置宏一覽

宏名含義類型典型用途
__FILE__當前源文件名 (含路徑)字符串常量日誌、錯誤定位、斷言
__LINE__當前行號整數常量同上
__DATE__編譯日期 "Mmm dd yyyy"字符串版本信息、構建時間戳
__TIME__編譯時間 "hh:mm:ss"字符串同上
__func__ / __FUNCTION__當前函數名 (C99 標準 / GCC 擴展)字符串函數級日誌追蹤
__STDC__是否符合 ANSI C 標準 (1/0)整數編譯器特性檢測

實戰示例:構建調試輸出宏

#include <stdio.h>

// 封裝調試宏:自動包含文件、行號、函數名
#define DEBUG_LOG(fmt, ...) \
    printf("[DEBUG] %s:%d %s() " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)

int show() {
    DEBUG_LOG("Enter show()");
    printf("hello\n");
    DEBUG_LOG("Leave show()");
    return 0;
}

int main() {
    DEBUG_LOG("Program start");
    show();
    DEBUG_LOG("Program end");
    return 0;
}

運行輸出

[DEBUG] test.c:15 main() Program start
[DEBUG] test.c:8 show() Enter show()
hello
[DEBUG] test.c:11 show() Leave show()
[DEBUG] test.c:18 main() Program end

進階應用場景

1. 斷言增強版

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

2. 內存分配追蹤

#define MALLOC(size) my_malloc(size, __FILE__, __LINE__)

void* my_malloc(size_t size, const char *file, int line) {
    void *p = malloc(size);
    printf("[ALLOC] %p size=%zu at %s:%d\n", p, size, file, line);
    return p;
}

3. 異常棧回溯輔助 (配合 addr2line)

在崩潰處打印 __FILE__、__LINE__,結合編譯時 -g 生成的調試信息,可快速定位源碼位置。

注意事項

  • 展開時機:預處理階段,非運行時。宏展開位置決定值,而非調用位置。
  • __func__ 是 C99 標準變量 (靜態字符數組),__FUNCTION__ 是 GCC/MSVC 擴展,建議用 __func__ 保證可移植性。
  • 字符串化運算符 # 可將宏參數變為字符串 (如 #cond → "cond")。
  • 連接運算符 ## 可拼接 Token。

總結

內置宏是 C 語言「編譯期感知運行上下文」的少數機制之一。善用 __FILE__、__LINE__、__func__ 封裝統一的日誌/斷言/追蹤宏,能將調試效率提升數倍,是從「寫代碼」進階為「工程化開發」的標誌性技能。

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