gcc和g++常用編譯參數
-w -W -Wall
-w 關閉編譯警告。平時編寫c/c++代碼如果不規範,編譯的時候會拋出很多警告。但是一般的警告都是可以忽略的,比如類型轉換。編譯的時候可以加-w關閉警告
-W 也是關閉編譯警告,但是比-w智能一些,它只會顯示編輯器認為會出錯的警告
-Wall, 顯示所有警告。
比如下面的代碼,test.c
gcc -o a.out test.c -Wall, 把所有的警告都顯示出來了,沒有使用的變量i,在void函數返回了double。
gcc -o a.out test.c -W, 只顯示了編譯器認為會出錯的警告, 沒有使用變量i的那個警告編譯器認為不會出錯,所以沒有輸出。
gcc -o a.out test.c -w, 屏蔽了所有警告,只輸出錯誤
-g -g3
gcc 支持4中級別的調試信息,-g0表示不生成調試信息,-g3表示生成最多的調試信息。-g默認為-g2。一般的調試信息包括行號,函數,外部變量。-g3包含其他額外的調試信息,比如宏定義。
-O1 -O2 -O3 -Os
-O系列選項主要用於優化代碼。
-O和-O1是等價的,不影響編譯速度,並且會采用一些優化算法,降低代碼大小並提高代碼運行速度。
-O2,會降低編譯速度,但是除了包含-O1的優化算法之外,還會采用一些其他的優化算法來提高代碼運行速度。
-O3,除了包含-O2所有的優化外,會采取一些向量化算法,提高代碼的並行執行程度,使之更充分地利用現代cpu的流水線和cache。
-Os,-O3即使是增加代碼的大小,也要提高運行速度。而這個選項在-O2的基礎上,盡量減少目標的大小,這個經常用於存儲量比較小的設備。
-fno-strict-aliasing
當優化級別在-O2即以上時,strict-aliasing會被采用。 編譯器會假設代碼中沒有強制轉換,從而會使用更加激進的優化算法對代碼進行優化。也就是說,代碼中如果存在類似於下面的代碼就會出錯:
int num = 1.0;
double *p = (int *)(&num);
所以當優化級別在-O2及以上時,應該使用-fno-strict-aliasing關閉strict-aliasing。如果可以確保代碼中不存在類似於上述的代碼,那就不要關閉。據mysql的worklog描述,代碼優化速度還是很可觀的。
-fPIC和-shared
編譯動態庫時常用的兩個選項。fPIC告訴編譯器編譯與地址無關的代碼(position independent code)。代碼中涉及到的地址都是相對地址,絕對地址運行時通過GOT計算得到。-shared告訴編譯器編譯的是一個動態庫。如果沒有-shared,編譯器會以找不到main函數而失敗返回。
-wl,-rpath=...
如果一份代碼使用了自己編寫的動態庫,而且沒有放在運行時查找動態庫的默認路徑中。在這臺機器上編譯,換個目錄執行,就會報找不到動態庫的錯誤。編譯時使用的-L選項只是在程序鏈接成可執行文件時候用的,程序啟動時候仍然會發生找不到庫的情況。如果編譯的時候這樣: -wl, -rpath=path_of_lib(絕對路徑), 那麽在程序運行的時候,就不會出現動態庫明明存在,但是找不到的情況了。
gcc和g++常用編譯參數