c 編譯過程簡介

2021-08-08 05:38:35 字數 1415 閱讀 5048

編譯過程簡介

目標檔案:編譯後生成的檔案,以機器碼的形式包含了編譯單元裡所有的函式和資料、匯出符號表、未解決符號表、位址重定向表

第二種是動態鏈結程式(動態庫)將它與另乙個可

執行檔案及其它的共享目標檔案結合到一起,建立乙個程序映象

可執行檔案

.o檔案在編譯後就能獲得,但是庫檔案、可執行檔案都需要在鏈結後才能獲得

c++程式編譯過程圖

編譯過程

編譯、優化階段

彙編 3張表:.o檔案至少要提供3張表

例子:

鏈結過程

在乙個檔案中引用的符號同該符號在另外乙個檔案中的定義連線起

來,使得所有的這些目標檔案成為乙個能夠被作業系統裝入執行的統

一整體。

具體工作:

當鏈結器進行鏈結的時候,首先決定各個目標檔案在最終可執行檔案裡的位置。然後訪問所有目標檔案的位址重定義表,對其中記錄的位址進行重定向(加上乙個偏移量,即該編譯單元在可執行檔案上的起始位址)。然後遍歷所有目標檔案的未解決符號表,並且在所有的匯出符號表裡查詢匹配的符號,並在未解決符號表中所記錄的位置上填寫實現位址。最後把所有的目標檔案的內容寫在各自的位置上,再作一些另的工作,就生成乙個可執行檔案。

鏈結方式

貝到最終的可執行程式中。這樣該程式在被執行時這些**將被裝入

到該程序的虛擬位址空間中。

記錄下共享物件的名字以及其它少量的登記資訊。在此可執行檔案被

空間。動態鏈結程式將根據可執行程式中記錄的資訊找到相應的函式

**。兩種鏈結方式的比較

c/c++中提供的一些特性

static:如果該關鍵字位於全域性函式或者變數的宣告前面,表明該編譯單元不匯出這個函式或變數,因些這個符號不能在別的編譯單元中使用(內部鏈結)。如果是static區域性變數,則該變數的儲存方式和全域性變數一樣,但是仍然不匯出符號。

為什麼標頭檔案裡一般只可以有宣告不能有定義:標頭檔案可以被多個編譯單元包含,如果標頭檔案裡面有定義的話,那麼每個包含這標頭檔案的編譯單元都會對同乙個符號進行定義,如果該符號為外部鏈結,則會導致duplicated external symbols鏈結錯誤。

為什麼公共使用的內聯函式要定義於標頭檔案裡:因為編譯時編譯單元之間互不知道,如果內聯被定義於.cpp檔案中,編譯其他使用該函式的編譯單元的時候沒有辦法找到函式的定義,因些無法對函式進行展開(內聯函式不展開,即不採用在使用處標記函式**再跳轉的方式,而是直接將**嵌入)。所以如果內聯函式定義於.cpp裡,那麼就只有這個.cpp檔案能使用它。

.h中的inline 函式可以被多個cpp包含而不造成符號衝突,因為它會被直接嵌入到呼叫的地方,內部聯結不形成外部符號,對外不可見

常見編譯器

makefile及make工具

常見編譯器使用方法

編譯錯誤解析

編譯過程簡介

被隱藏的過程 預編譯 處理所有的注釋,以空格代替 將所有的 define刪除刪除 並且展開所有的巨集定義 處理條件編譯指令 if,ifdef,elif,else,endif 處理 include 展開被包含的檔案 保留編譯器需要使用的 pragma指令指令 預處理指令 編譯 對預處理檔案進行一系列詞...

編譯過程簡介

程式編譯和連線的過程如下所示 編譯器的工作包括 預編譯 編譯 彙編 預編譯 處理所有的注釋,以空格代替 將所有的 define刪除,並且展開所有的巨集定義 處理條件編譯指令 if,ifdef,elif,else,endif 處理 include,展開被包含的檔案 保留編譯器需要使用的 pragma指...

gcc簡介及編譯過程

1 編譯器 gcc 簡介 linux系統下的 gcc gnu c compiler 是gnu推出的功能強大 效能優越的多 平台編譯器,它是gnu的代表作品之一,gcc是可以在多種硬體平台上編譯出可 執行檔案的超級編譯器,其執行效率比一般的編譯器要高出20 30 編譯器能 將c c 語言源程式 組合語...