C 編譯,執行過程 具體解釋。

2021-09-07 13:47:07 字數 3118 閱讀 5881

要更深入了解c++, 必需要知道乙個程式從開始到結束都幹了些什麼, 怎麼幹的。

所以我從c++編譯到執行過程,解析下程式是怎麼跑的。

首先,初略的說一下之前c++的編譯過程。c++編譯過程包含預編譯-》彙編-》編譯-》鏈結。稱為乙個可執行檔案。(windows平台下為.exe檔案)。

預編譯主要展開包括的標頭檔案,巨集定義等操作。比如乙個簡單的main程式,編譯預編譯後,的檔案對照。

假設定了那個巨集。那麼巨集裡面的內容也會顯示出來。標頭檔案也是。假設你包括了你乙個.h 檔案,那麼整個.**件會包括進來。

彙編過程,就是把已經預編譯的檔案編譯成彙編**的過程。整個過程會包括語法,詞法的分析,和一些優化操作。

編譯過程事實上是跟彙編能夠合成乙個階段,變成目標**。也就是二進位制檔案。

鏈結過程是將單個編譯後的檔案鏈結成乙個可執行程式。前面的預編譯、彙編、編譯都是正對單個檔案,以乙個檔案為乙個編譯單元,而鏈結則是將全部關聯到的編譯後單元檔案和應用的到庫檔案。進行一次鏈結處理,之前編譯過的檔案 假設實用到其它檔案中面定義到的函式。全域性變數。在這個過程中都會進行解析。

首先看看編譯後的檔案樣子(已vs2012編譯後的obj檔案為樣例。不同編譯器 樣式可能會不同。

編譯前的檔案

#include "car.h"

int main(int argc, char* ar**)

編譯後的樣子(因為編譯後的檔案 資訊太多 僅僅貼出裡面未解析符號部分。

undef:00002dc4 ; int __thiscall car::car(car *__hidden this)

undef:00002dc4                 extrn ?

0car@@qae@xz:near ; code xref: _main+63p

undef:00002dc8 ; int __thiscall car::~car(car *__hidden this)

undef:00002dc8                 extrn ??

1car@@qae@xz:near

undef:00002dc8                                         ; code xref: car::`scalar deleting destructor'(uint)+26p

undef:00002dcc ; __fastcall _rtc_checkstackvars(x, x)

undef:00002dcc                 extrn @_rtc_checkstackvars@8:near

undef:00002dcc                                         ; code xref: std::_string_alloc<0,std::_string_base_types>>::_alloc_proxy(void)+68p

undef:00002dcc                                         ; $ln19+72p ...

undef:00002dd0 ; __fastcall __security_check_cookie(x)

undef:00002dd0                 extrn @__security_check_cookie@4:near

undef:00002dd0                                         ; code xref: __ehhandler$??$construct@padaapad@?$allocator@d@std@@qaexpapadaapad@z+fp

undef:00002dd0                                         ; __ehhandler$??

$construct@u_container_proxy@std@@u12@@?$allocator@u_container_proxy@std@@@std@@qaexpau_container_proxy@1@$$qau21@@z+fp ...

undef:00002dd4 ; __stdcall _cxxthrowexception(x, x)

編譯後的檔案用(用反彙編成彙編**檢視) 當中實現函式會變成一堆彙編指令。而那些引用到的在其它檔案中面實現的函式將會變成乙個特點的符號(如上面中的呼叫car類的建構函式 extrn ??0car@@qae@xz:near)這些符號稱做為解析的符號。表示在鏈結的時候須要被解析。

符號的生成名稱詳細跟編譯器有關,可是會保證乙個類的某個函式名稱在同乙個編譯裡面必須是唯一的,由於我們在預編譯階段已經把car.h包括進來所以編譯器能正確生成這個函式的名字。然後在鏈結的時候 會找到改名字的函式,把此標識名字替換為函式的位址。這樣就實現的鏈結。

在符號解析(symbol resolution)階段,鏈結器依照全部目標檔案和庫檔案出如今命令列中的順序從左至右依次掃瞄它們。在此期間它要維護若干個集合:(1)集合e是將被合併到一起組成可執行檔案的全部目標檔案集合。(2)集合u是未解析符號(unresolved symbols,比方已經被引用可是還未被定義的符號)的集合。(3)集合d是全部之前已被增加到e的目標檔案定義的符號集合。一開始,e、u、d都是空的。

(1): 對命令列中的每個輸入檔案f,鏈結器確定它是目標檔案還是庫檔案,假設它是目標檔案。就把f增加到e,並把f中未解析的符號和已定義的符號分別增加到u、d集合中。然後處理下乙個輸入檔案。

(2): 假設f是乙個庫檔案,鏈結器會嘗試把u中的全部未解析符號與f中各目標模組定義的符號進行匹配。假設某個目標模組m定義了乙個u中的未解析符號,那麼就把 m增加到e中,並把m中未解析的符號和已定義的符號分別增加到u、d集合中。不斷地對f中的全部目標模組反覆這個過程直至到達乙個不動點(fixed point),此時u和d不再變化。而那些未增加到e中的f裡的目標模組就被簡單地丟棄,鏈結器繼續處理下一輸入檔案。

(3): 假設處理過程中往d增加乙個已存在的符號,或者當掃瞄全然部輸入檔案時u非空。鏈結器報錯並停止動作。否則,它把e中的全部目標檔案合併在一起生成可執行檔案。



C編譯執行的過程

c編譯執行是c語言必學的的。從巨集觀上來說主要分成了 c源 編譯 鏈結 執行 從微觀上來說 c源程式標頭檔案 預編譯處理 cpp 編譯程式本身 優化程式 匯程式設計序 鏈結程式 可執行檔案 a 預編譯處理 將偽指令和特殊的符號進行處理。預處理就是將原始檔的包含標頭檔案,巨集定義,條件編譯等進行簡單的...

C程式編譯執行過程

c語言從源 到可執行檔案的過程 1 編譯預處理 讀取c源 對其中的偽指令 以 開頭的指令 和特殊符號進行處理 偽指令主要包括以下四個方面 1.1 巨集定義指令 define 定義巨集 undef 取消巨集的定義 預定義巨集 標準c中定義了一些物件巨集,這些巨集的名稱以 兩個下劃線 開頭和結尾,並且都...

C 編譯,執行過程 詳解。

要更深入了解c 必須要知道乙個程式從開始到結束都幹了些什麼,怎麼幹的。所以我從c 編譯到執行過程,解析下程式是怎麼跑的。首先,初略的說一下之前c 的編譯過程,c 編譯過程包括預編譯 彙編 編譯 鏈結。稱為乙個可執行檔案。windows平台下為.exe檔案 預編譯主要展開包含的標頭檔案,巨集定義等操作...