《gcc五分鐘系列》第九節:編譯過程
接下來幾節,我會講一些編譯期相關的優化選項及預編譯期相關的優化選項。至于彙編期和連結期……我就完全不懂了。我不懂彙編語言。連結期也涉及了很多我完全不懂的問題。
那麼,編譯期是什麼意思?預編譯期又是什麼意思?這個涉及到編譯的整個過程。我記得前面某節好像提到過這個話題,這裡詳細的講一下。
從源代碼(xxx.cpp)生成可執行檔案(a.out)一共分為四個階段:
1、預編譯階段:
此時編譯器會處理源代碼中所有的預編譯指令。預編譯指定非常有特點,全部以“#”開頭。
想想,以“#”開頭的指令有哪些?
不同的指令有不同的處理方法,#include指令的處理方法就是赤裸裸的複制粘貼。将#include後面的檔案的内容赤裸裸地複制粘貼到#include指令所在的位置。#define指令分為帶參宏和不帶參宏。#define指令的處理方法,學名叫宏展開。其實不帶參宏的處理方法就是赤裸裸的字元串替換。之後會産生一篇完全不包含預編譯指令的代碼。
使用gcc的-e選項可以檢視預編譯結果:
g++ -e xxx.cpp
但是這個指令不會把處理結果儲存在檔案中,而是放在标準輸出中。
例子:見本文最後例一。
2、彙編階段:
此時編譯器會将預處理過的代碼進行彙編。
使用gcc的-s選項可以檢視彙編結果:
g++ -s xxx.cpp
之後會在目前目錄下産生一個xxx.s的檔案,裡面儲存的是彙編代碼。
彙編我不懂,就不帖了。
3、編譯階段:
此時編譯器會将彙編代碼編譯成目标檔案。
使用gcc的-c選項可以生成目标檔案:
g++ -c xxx.s
也可以從源代碼直接生成目标檔案:
g++ -c xxx.cpp
gcc會通過擴充名自動判斷處理的是彙編代碼還是c++代碼。
到此,編譯器已經完成它的全部工作。
4、連結階段:
此時已經沒有編譯器的事情了。連結工作交由連結器來處理。連結器會将多個目标檔案連結成可執行檔案。
我們可以通過gcc來進行連結,但是實際上,gcc還是調用ld指令來完成連結工作的。
g++ xx1.o xx2.o
本節完。
計劃先講編譯階段的pipe選項、o選項和w選項。因為編譯階段事情比較少。
然後講預編譯階段的i選項和d選項。
例一: