天天看點

不常見但是很有用的gcc指令行選項(一)

軟體工具通常情況下會提供多個功能以供選擇,但是如你所知的,不是所有的功能都能被每個人用到的。公正地講,這并不是設計上的錯誤,因為每個使用者都會有自己的需求,他們隻在他們的領域内使用該工具。然而,深入了解你所使用的工具也是很有益處的,因為你永遠不知道它的某個功能會在什麼時候派上用場,進而節省下你寶貴的時間。

不常見但是很有用的gcc指令行選項(一)

舉一個例子:編譯器。一個優秀的程式設計語言編譯器總是會提供極多的選項,但是使用者一般隻知道和使用其中很有限的一部分功能。更具體點來說,比如你是 c 語言開發人員,并将 linux 作為你的開發平台,那麼你很有可能會用到 gcc 編譯器,這個編譯器提供了 (幾乎) 數不清的指令行選項清單。

你知道,你可以讓 gcc 儲存每個編譯階段的輸出嗎?你知道用于生成警告的 -wall 選項,它并不會包含一些特殊的警告嗎?gcc 的很多指令行選項都不會經常用到,但是它們在某些特定的情況下會變得非常有用,例如,當你在調試代碼的時候。

是以在本文中,我們會介紹這樣的幾個選項,提供所有必要的細節,并通過簡單易懂的例子來解釋它們。

但是在開始前,請注意本文中所有的例子所使用的環境:基于 ubuntu 16.04 lts 作業系統,gcc 版本為 5.4.0。

在每個編譯階段檢視中間代碼的輸出

你知道在通過 gcc 編譯 c 語言代碼的時候大體上共分為四個階段嗎?分别為預處理 -> 編譯 -> 彙編 -> 連結。在每個階段之後,gcc 都會産生一個将移交給下一個階段的臨時輸出檔案。但是生成的都是臨時檔案,是以我們并不能看到它們——我們所看到的隻是我們發起編譯指令,然後它生成的我們可以直接運作的二進制檔案或可執行檔案。

但是比如說在預處理階段,如果調試時需要檢視代碼是如何進行處理的,你要怎麼做呢?好消息是 gcc 編譯器提供了相應的指令行選項,你可以在标準編譯指令中使用這些選項獲得原本被編譯器删除的中間檔案。我們所說的選項就是-save-temps。

以下是 gcc 手冊中對該選項的介紹:

永久存儲臨時的中間檔案,将它們放在目前的檔案夾下并根據源檔案名稱為其命名。是以,用 -c -save-temps 指令編譯 foo.c 檔案時會生成 foo.i foo.s 和 foo.o 檔案。即使現在編譯器大多使用的是內建的預處理器,這指令也會生成預處理輸出檔案 foo.i。

當與 -x 指令行選項結合使用時,-save-temps 指令會避免覆寫與中間檔案有着相同擴充名的輸入源檔案。相應的中間檔案可以通過在使用 -save-temps 指令之前重命名源檔案獲得。

以下是怎樣使用這個選項的例子:

gcc -wall -save-temps test.c -o test-exec 

下圖為該指令的執行結果,驗證其确實産生了中間檔案:

不常見但是很有用的gcc指令行選項(一)

是以,在截圖中你所看到的 test.i、test.s、 test.o 檔案都是由 -save-temps 選項産生的。這些檔案分别對應于預處理、編譯和連結階段。

讓你的代碼可調試和可分析

你可以使用專有的工具調試和分析代碼。如 gdb 就是專用于調試的工具,而 gprof 則是熱門的分析工具。但你知道 gcc 特定的指令行選項也可以讓你的代碼可調試和可分析嗎?

讓我們開始調試之路吧!為了能在代碼調試中使用 gdb,你需要在編譯代碼的時候使用 gcc 編譯器提供的 -g 選項。這個選項讓 gcc 生成 gdb 需要的調試資訊進而能成功地調試程式。

如果你想要使用此選項,建議您詳細閱讀 gcc 手冊提供的有關此選項的詳細資訊——在某些情況下,其中的一些内容可能是至關重要的。 例如,以下是從手冊頁中摘錄的内容:

gcc 允許在使用 -g 選項的時候配合使用 -o 選項。優化代碼采用的便捷方式有時可能會産生意想不到的結果:某些你聲明的變量可能不複存在;控制流可能會突然跳轉到你未曾預期的位置;一些語句也許不會執行,因為它們已經把常量結果計算了或值已經被儲存;一些語句可能會在不同地方執行,因為它們已經被移出循環。

然而優化的輸出也是可以調試的。這就使得讓優化器可以合理地優化或許有 bug 的代碼。

不隻是 gdb,使用 -g 選項編譯代碼,還可以開啟使用 valgrind 記憶體檢測工具,進而完全發揮出該選項的潛力。或許還有一些人不知道,mencheck 工具被程式員們用來檢測代碼中是否存在記憶體洩露。你可以在這裡參見這個工具的用法。

繼續往下,為了能夠在代碼分析中使用 gprof 工具,你需要使用 -pg 指令行選項來編譯代碼。這會讓 gcc 生成額外的代碼來寫入分析資訊,gprof 工具需要這些資訊來進行代碼分析。gcc 手冊 中提到:當編譯你需要資料的源檔案時,你必須使用這個選項,當然連結時也需要使用它。為了能了解 gprof 分析代碼時具體是如何工作的,你可以轉到我們的網站專用教程進行了解。

注意:-g 和 -pg 選項的用法類似于上一節中使用 -save-temps 選項的方式。

結論

我相信除了 gcc 的專業人士,都可以在這篇文章中得到了一些啟發。嘗試一下這些選項,然後觀察它們是如何工作的。同時,請期待本教程系列的下一部分,我們将會讨論更多有趣和有用的 gcc 指令行選項。

作者:ansh

來源:51cto

繼續閱讀