IDE (VS, CLion) 一鍵運行隱藏了細節。掌握 g++ 四階段流程,能診斷「頭文件重複包含」「模板報錯」「鏈接錯誤」「符號衝突」等疑難雜癥,也是高級優化 (LTO, PCH) 的前提。
| 後綴 | 含義 |
|---|---|
.c | C 源文件 |
.cpp/.cc/.cxx/.C | C++ 源文件 |
.h/.hpp/.hxx | 頭文件 |
.i/.ii | 預處理輸出 |
.s/.S | 匯編源文件 |
.o/.obj | 目標文件 (機器碼) |
.a/.lib | 靜態庫 |
.so/.dll/.dylib | 動態庫 |
#include:展開頭文件內容 (遞歸)。#define:宏替換、條件編譯 (#if/#ifdef)。#line),供後續錯誤定位。g++ -E hello.cpp > hello.i
# 查看 hello.i 尾部可見 iostream 內容已展開,宏已替換
g++ -S hello.cpp
# hello.s 含 .text .data .bss 段指令,如 call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
std::cout) 保留在重定位表,待鏈接階段解決。g++ -c hello.cpp
# hello.o 為二進制,objdump -d hello.o 可反匯編查看
std::cout) 綁定到定義處 (libstdc++.so/a)。_start → __libc_start_main → main)。g++ -o hello hello.cpp
# 等同於: g++ -c hello.cpp -o hello.o && g++ hello.o -o hello
./hello # 輸出 "hello world!"
ar rcs libfoo.a foo.o bar.o 打包目標文件。g++ -shared -fPIC -o libfoo.so foo.cpp。| 錯誤現象 | 階段 | 典型原因 |
|---|---|---|
fatal error: xxx.h: No such file | 預處理 | 頭文件路徑缺失 (-I) |
error: 'cout' was not declared | 編譯 | 缺 #include <iostream> 或 using namespace std; |
undefined reference to `func()' | 鏈接 | 函數聲明無定義、未鏈接庫 (-l)、虛函數無定義 |
multiple definition of `var' | 鏈接 | 頭文件定義全局變量 (應 extern 声明 + .cpp 定義) |
template instantiation error | 編譯 | 模板定義在 .cpp 未显式实例化 (模板代碼應在頭文件) |
g++ -x c++-header common.h -o common.h.gch,加速大型專案編譯。g++ -flto -O2,跨文件內聯、死代碼消除。-c 參數,構建系統並行編譯核心。nm -C hello.o (C++ 解碼名)、objdump -t。「預處理展開 → 編譯優化生成匯編 → 匯編生成機器碼目標文件 → 鏈接解析符號生成可執行文件」是 C++ 源碼變程序的鐵律。熟練使用 -E/-S/-c 斷點調試編譯流程,是從「會用語言」進階為「懂底層工程師」的必經之路。