GCC 依序搜尋以下目錄(#include <...>):
/usr/local/includelibdir/gcc/target/version/include/usr/target/include/usr/includeC++ 額外搜尋:libdir/../include/c++/version。
target 為編譯目標三元組(如 x86_64-linux-gnu),version 為 GCC 版本號。
| 選項 | 作用 |
|---|---|
-I dir | 新增 dir 到搜尋路徑最前端 |
-nostdinc | 禁止搜尋標準系統目錄(編譯核心適用) |
-I- | 分隔符:前者僅搜尋 #include "...",後者搜尋所有 |
-iquote dir | 僅為 #include "..." 新增路徑(推薦替代 -I-) |
注意:-nostdinc不影響-I dir指定的目錄。目錄名若為-,需寫成-I./-區分。
/* File: foo.h */ #ifndef FILE_FOO_SEEN #define FILE_FOO_SEEN /* 整個頭文件內容 */ #endif /* !FILE_FOO_SEEN */
__FILE_H__(雙底線開頭),使用者頭文件建議用 _FILE_H_(單底線)避免衝突。#import:Objective-C 機制,將「只包含一次」責任推給使用者,違反封裝原則。#pragma once:非標準,部分預處理器不支援,移植性風險高。#line 宏預處理器自動插入 #line 指令,讓編譯器錯誤訊息能精確定位到原始檔案行號。
glibc 許多函式同時提供宏與真實函式兩種實現(如 abs())。宏展開產生內聯程式碼,速度快但偵錯時行號指向宏定義處而非呼叫處,極難除錯。
#include <stdlib.h> abs(i); // 編譯器自行選擇宏或函式 (abs)(i); // 加括號阻止宏展開,強制函式呼叫 #undef abs abs(i); // 取消宏定義後強制函式呼叫
掌握 GCC 頭文件搜尋規則、正確使用 Wrapper #ifndef、理解函式宏的偵錯限制並會強制使用函式版本,是編寫可移植、可維護、可除錯 C/C++ 程式的核心基本功。