GCC的編譯流程分爲以下4個步驟
- 預處理(pre-processing)
- 編譯(compiling)
- 彙編(assembling)
- 鏈接(linking)
編譯器通過程序的擴展名來分辯編寫源程序所用的語言。由於不同的程序所需要執行編譯的步驟是不同的,因此GCC根據不同的後綴名對它們進行相應處理。
GCC所支持不同後綴名的處理方式
後 綴 名 | 所對應的語言 | 編 譯 流 程 |
.c | C 原始程序 | 預處理、編譯、彙編 |
.C/.cc/.cxx | C++原始程序 | 預處理、編譯、彙編 |
.m | Objective C 原始程序 | 預處理、編譯、彙編 |
.i | 已經過預處理的C 原始程序 | 編譯、彙編 |
.ii | 已經過預處理的C++原始程序 | 編譯、彙編 |
.s/.S | 彙編語言原始程序 | 彙編 |
.h | 預處理文件(頭文件) | (不常出現在指令行) |
.o | 目標文件 | 鏈接 |
.a/.so | 編譯後的庫文件 | 鏈接 |
GCC編譯流程語法
GCC基本語法
gcc [option | filename]
這裏的 option 是 GCC 使用時的一些選項,通過指定不同的選項 GCC 可以實現強大的功能。這裏的 filename 則是 GCC 要編譯的文件,GCC 會根據用戶所指定的編譯選項以及所識別的文件後綴名來對編譯文件進行相應的處理。
- 預處理階段
GCC 的選項“-E”可以使編譯器在預處理結束時就停止編譯,選項“-o”是指定 GCC 輸出的結果,其命令格式如下:
gcc –E –o [目標文件] [編譯文件]
例如: gcc –E –o hello.i hello.c
2.編譯階段
編譯器在預處理結束之後使用。GCC首先要檢查代碼的規範性、是否有語法錯誤等,以確定代碼實際要做的工作,在檢查無誤後,就開始把代碼翻譯成彙編語言。GCC的選項“-S”能使編譯器在進行完編譯之後就停止。
gcc –S –o [目標文件] [編譯文件]
例如: gcc –S –o hello.s hello.i
3.彙編階段
彙編階段是把編譯階段生成的“.s”文件生成目標文件,讀者在此使用選項“-c”就可看到彙編代碼已轉化爲“.o”的二進制目標代碼了。
gcc –c [目標文件] [編譯文件]
例如: gcc –c hello.s –o hello.o
4.鏈接階段
成功編譯之後,就進入了鏈接階段。在這裏涉及一個重要的概念:函數庫。
完成鏈接之後,GCC 就可以生成可執行文件,其命令如下:
gcc hello.o –o hello
GCC警告提示
GCC 的警告提示選項有很多種類型,主要可分爲“-Wall”類和非“-Wall”類。
1.Wall類警告提示
這一類警告提示選項佔了GCC警告選項的90%以上,它不僅包含打開所有警告等功能,還可以單獨對常見錯誤分別指定警告。
選項 | 作用 |
-Wall | 打開所有類型語法警告,建議讀者養成使用該選項的習慣 |
-Wchar-subscripts | 如果數組使用char 類型變量作爲下標值的話,則發出警告。因爲在某些平臺上可能默認爲 signed char,一旦溢出,就可能導致某些意外的結果 |
-Wcomment | 當“/*”出現在“/* …… */”註釋中,或者“\”出現在“// ……”註釋結尾處時,使用-Wcomment 會給出警告,它很可能會影響程序的運行結果 |
-Wformat | 檢查 printf 和 scanf 等格式化輸出輸入函數的格式字符串與參數類型的匹配情況,如果發現不匹配則發出警告。某些時候格式字符串與參數類型的不匹配會導致程序運行錯誤, 所以這是個很有用的警告選項 |
-Wimplicit | 該警告選項實際上是-Wimplicit-int 和-Wimplicit-function-declaration 兩個警告選項的集合。前者在聲明函數卻未指明函數返回類型時給出警告,後者則是在函數聲明前調用該函數時給出警告 |
-Wmissing-braces | 當聚合類型或者數組變量的初始化表達式沒有充分用括號“{}”括起時,給出警告 |
-Wparentheses | 這是一個很有用的警告選項,它能幫助用戶從那些看起來語法正確但卻由於操作符優先級或者代碼結構“障眼”而導致錯誤運行的代碼中解脫出來 |
-Wsequence-point | 關於順序點(sequence point),在 C 標準中有解釋,不過很晦澀。我們在平時編碼中儘量避免寫出與實現相關、受實現影響的代碼便是了。而-Wsequence-point 選項恰恰可以幫我們這個忙,它可以幫我們查出這樣的代碼來,並給出其警告 |
-Wswitch | 這個選項的功能淺顯易懂,通過文字描述也可以清晰地說明。當以一個枚舉類型(enum) 作爲 switch 語句的索引但卻沒有處理 default 情況,或者沒有處理所有枚舉類型定義範圍內的情況時,該選項會給出警告 |
-Wunused-function | 警告存在一個未使用的static 函數的定義或者存在一個只聲明卻未定義的static 函數 |
-Wunused-label | 用來警告存在一個使用了卻未定義或者存在一個定義了卻未使用的label |
-Wunused-variable | 用來警告存在一個定義了卻未使用的局部變量或者非常量static 變量 |
-Wunused-value | 用來警告一個顯式計算表達式的結果未被使用 |
-Wunused-parameter | 用來警告一個函數的參數在函數的實現中並未被用到 |
-Wuninitialized | 該警告選項用於檢查一個局部自動變量在使用之前是否已經初始化或者在一個 longjmp 調用可能修改一個non-volatile automatic variable 時給出警告 |
2.非 Wall 類警告提示
非 Wall 類的警告提示中最爲常用的有以下兩種:“-ansi”和“-pedantic”。
-
“-ansi”。該選項強制 GCC 生成標準語法所要求的告警信息,儘管這還並不能保證所有沒有警告的程序都是符合ANSI C 標準的。
-
“-pedantic”。該選項允許發出 ANSI C 標準所列的全部警告信息,同樣也保證所有沒有警告的程序都是符合 ANSI C 標準的。