將源**或者標頭檔案經過預編譯成乙個.i檔案。例如c++副檔名是.cpp,標頭檔案的副檔名可能是.hpp,預編譯後的副檔名是.i
預編譯的過程相當於下面的命令:
對c語言檔案的處理:gcc –e 原始檔 –o目標檔案
對c++語言的檔案的處理:g++ gcc –e 原始檔 –o目標檔案
例如:gcc –e hello.c –o hello.i預編譯需要做的工作:主要處理源**中以「#」開始的預編譯命令
刪除所有的#define,並且展開所有的巨集定義。
處理所有預編譯條件比如「#if」、「#ifdef」、「#elif」、「#else」、「endif」。
處理「#include」預編譯指令,將包含的檔案插入到該預處理指令的位置。這整個過程是遞迴進行的,也就是說被包含的檔案可能還包含其他檔案。
刪除所有的注釋「//」和「/**/」。
新增行號和檔名標識,以便於編譯時編譯器產生除錯用的行號資訊及用於編譯時產生編譯錯誤或警告時能夠顯示行號。
保留所有的#pragma編譯器指令,因為編譯器須要使用它們。
經過預編譯後的.i檔案不包含任何的巨集定義,因為所有的巨集已經被展開,並且包含的檔案也已經插入到.i檔案中
就是將預處理完的檔案進行,詞法分析、語法分析、語義分析及優化後生產相應的彙編**檔案,是整個過程中的核心。
使用以下命令:
gcc –s hello.i –o hello.s詞法分析:**被輸入到掃瞄器,利用演算法將**分割成一系列的記號。詞法分析產生的記號一般可以分為:關鍵字、識別符號、字面量(包含數字字串)和特殊符號(如加號、減號)。在識別記號同時,掃瞄器還做了其他工作,比如將識別符號放入符號表,將數字、字串常量放入文字表中。
語法分析:接下來語法分析器對記號進行語法分析,產生語法樹;在c語言中每個語句其實就是乙個表示式,語法樹就是以表示式為節點的樹。在語法分析的同時,許多符號優先順序和含義也被確定下來。如果表示式錯誤,編譯器會報出語法階段的錯誤。
語義分析:語義分析由語義分析器來完成。語法分析僅僅完成了對表示式的語法層次的分析,並無法知道語句是否有意義。語義分析器只能識別靜態語義;靜態語義指的是在編譯階段能確定的語義,對應的動態語義指的是在執行階段才能確定的語義;比如,將乙個浮點型別賦值給指標型別,語義分析器會發現型別不匹配,編譯器會報錯,這是在編譯期間就能識別的。像0作為除數就是在執行期間語義錯誤。
彙編器就是將彙編**轉變成可以執行的指令,每乙個彙編語句對應著一條機器指令,所以彙編器過程相對簡單。經過預編譯、編譯、彙編最終輸出目標檔案。
使用以下的命令:
gcc –c hello.s –o hello.o
組裝模組的過程就是鏈結。鏈結的主要內容就是處理各個模組中變數和函式的相互引用。鏈結過程主要包括了位址和空間分配、符號決議和重定位(當編譯本檔案時,編譯器不知道其他檔案中定義的變數,所以在沒有確定位址的情況下,將目標位址置為0,當與其他檔案鏈結起來的時候再將其位址進行修正,位址修正的過程叫做重定位)。
最基本的靜態鏈結就是將每個模組的源**檔案經過編譯得到目標檔案,目標檔案和庫檔案一起鏈結最終成為可執行檔案。
Linux 預編譯 編譯 彙編 鏈結過程
當我們拿到乙個.cpp的檔案,我們看到它的 但我們又是知道它是怎樣執行的?我們都知道我們所看到的 都是高階語言。但計算機底層只能識別像0,1這樣的低階語言,所以這也是乙個將c c 轉成組合語言然後再變成機器語言的過程。具體可分為預編譯 編譯 彙編 鏈結四個過程。一 在liunx中這四個階段的具體命令...
程式的預編譯,編譯,彙編,鏈結過程
預編譯過程主要處理那些源 檔案中的以 開始的預編譯指令。比如 include define 等,主要處理規則如下 1 將所有的 define 刪除,並且展開所有的巨集定義。2 處理所有條件預編譯指令,比如 if ifdef elif else endif 3 處理 include 預編譯指令,將被包...
預編譯標頭檔案及編譯鏈結過程
預編譯標頭檔案 在編寫程式的時候,有一些標頭檔案被許多檔案用到。例如 windows.h這樣的系統標頭檔案。如果不採用預編譯標頭檔案,那麼每個包含windows.h的檔案都需要編譯這個檔案。這將會增加編譯時間。正是為了解決這個問題,microsoft visual c 提出了預編譯標頭檔案的解決方法...