__LINE__、__FILE__、__FUNCTION__(C++11 為 __func__)是編譯器預先定義的預處理器宏,不需在專案屬性或標頭檔中宣告,編譯器在前處理階段自動替換為對應的編譯時期資訊。
| 宏名稱 | 標準 | 展開內容 | 常見用途 |
|---|---|---|---|
__LINE__ | C/C++ | 當前原始碼行號(整數常數) | 除錯日誌、斷言訊息 |
__FILE__ | C/C++ | 當前編譯檔案完整路徑(字串常值) | 日誌標記、錯誤定位 |
__FUNCTION__ | MSVC/GCC 擴充 | 當前函式名稱(字串常值) | 追蹤呼叫堆疊、效能分析 |
__func__ | C99 / C++11 | 當前函式名稱(區域靜態字元陣列) | 跨平台標準寫法 |
__DATE__ | C/C++ | 編譯日期 "Mmm dd yyyy" | 版本資訊 |
__TIME__ | C/C++ | 編譯時間 "hh:mm:ss" | 版本資訊 |
__cplusplus | C++ | C++ 標準版本號(如 201703L) | 條件編譯 |
__STDC__ | C | 符合 C 標準則為 1 | 條件編譯 |
編譯器前端(Frontend)在詞法分析與前處理階段,維護一個原始碼位置追蹤器。每當讀取一行原始碼,即更新行號計數器;遇到 #include 切換檔案時更新檔案名稱堆疊;進入函式定義時記錄函式名稱。當偵測到這些保留宏識別字時,直接以對應的編譯時期常數取代,不佔用執行期記憶體,也不產生函式呼叫開銷。
#include
#include
void log(const std::string& msg) {
std::cout << "[" << __FILE__ << ":" << __LINE__ << "] "
<< __FUNCTION__ << ": " << msg << std::endl;
}
int main() {
log("程式啟動");
return 0;
}
// 輸出範例:[main.cpp:12] main: 程式啟動
&__LINE__ 編譯錯誤)。__FUNCTION__ 為編譯器擴充,C++11 標準請用 __func__;MSVC 同時支援兩者。__FILE__ 路徑格式視編譯器而定(MSVC 為絕對路徑,GCC/Clang 為編譯指令給定的相對/絕對路徑)。內建宏是零成本的編譯時期資訊注入機制,廣泛用於除錯、日誌、斷言、版本標記等場景,善用它們能大幅提升程式碼可維護性與除錯效率。