gcc 和g++編譯選項詳解
gcc 提供了大量的警告選項,對程式碼中可能存在的問題提出警 告,通常可以使用-Wall來開啟以下警告:
-Waddress -Warray-bounds (only with -O2) -Wc++0x-compat
-Wchar-subscripts -Wimplicit-int -Wimplicit-function-declaration
-Wcomment -Wformat -Wmain (only for C/ObjC and unless
-ffreestanding) -Wmissing-braces -Wnonnull -Wparentheses
-Wpointer-sign -Wreorder -Wreturn-type -Wsequence-point
-Wsign-compare (only in C++) -Wstrict-aliasing -Wstrict-overflow=1
-Wswitch -Wtrigraphs -Wuninitialized (only with -O1 and above)
-Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value
-Wunused-variable
unused-function:警告宣告但是沒有定義的static函式;
unused- label:宣告但是未使用的標籤;
unused-parameter:警告未使用的函式引數;
unused-variable:宣告但 是未使用的本地變數;
unused-value:計算了但是未使用的值;
format:printf和scanf這樣的函式中的格式字元 串的使用不當;
implicit-int:未指定型別;
implicit-function:函式在宣告前使用;
char- subscripts:使用char類作為陣列下標(因為char可能是有符號數);
missingbraces:大括號不匹配;
parentheses: 圓括號不匹配;
return-type:函式有無返回值以及返回值型別不匹配;
sequence-point:違反順序點的程式碼,比如 a[i] = c[i++];
switch:switch語句缺少default或者switch使用列舉變數為索引時缺少某個變數的case;
strict- aliasing=n:使用n設定對指標變數指向的物件型別產生警告的限制程度,預設n=3;只有在-fstrict-aliasing設定的情況下有 效;
unknow-pragmas:使用未知的#pragma指令;
uninitialized:使用的變數為初始化,只在-O2時有 效;
以下是在-Wall中不會啟用的警告選項:
cast-align:當指標進行型別轉換後有記憶體對齊要求更嚴格時發出警告;
sign- compare:當使用signed和unsigned型別比較時;
missing-prototypes:當函式在使用前沒有函式原型時;
packed:packed 是gcc的一個擴充套件,是使結構體各成員之間不留記憶體對齊所需的空 間
padded:也是gcc的擴充套件,使結構體成員之間進行記憶體對齊的填充,會 造成結構體體積增大.
unreachable-code:有不會執行的程式碼時.
inline:當inline函式不再保持inline時 (比如對inline函式取地址);
disable-optimization:當不能執行指定的優化時.(需要太多時間或系統 資源).
可以使用 -Werror時所有的警告都變成錯誤,使出現警告時也停止編譯.需要和指定警告的引數一起使用.
優化:
gcc預設提供了5級優 化選項的集合:
-O0:無優化(預設)
-O和-O1:使用能減少目標文 件
-O2: 包含-O1的優化並增加了不需要在目標檔案大小和執行速度上進行折衷的優化.編譯器不執行迴圈展開以及函式內聯.此選項將增加編譯時間和目標檔案的執行性 能.
-Os:專門優化目標檔案大小,執行所有的不增加目標檔案大小的-O2優化選項.並且執行專門減小目標檔案大小的優化選項.
-O3: 開啟所有-O2的優化選項並且增加 -finline-functions, -funswitch-loops,-fpredictive-commoning, -fgcse-after-reload and -ftree-vectorize優化選項.
-O1包含的選項-O1通常可以安全的和除錯的選項一起使用:
-fauto-inc-dec -fcprop-registers -fdce -fdefer-pop -fdelayed-branch
-fdse -fguess-branch-probability -fif-conversion2 -fif-conversion
-finline-small-functions -fipa-pure-const -fipa-reference
-fmerge-constants -fsplit-wide-types -ftree-ccp -ftree-ch
-ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse
-ftree-fre -ftree-sra -ftree-ter -funit-at-a-time
以下所有的優化選項需要在名字 前加上-f,如果不需要此選項可以使用-fno-字首
defer-pop:延遲到只在必要時從函式引數棧中pop引數;
thread- jumps:使用跳轉執行緒優化,避免跳轉到另一個跳轉;
branch-probabilities:分支優化;
cprop- registers:使用暫存器之間copy-propagation傳值;
guess-branch-probability:分支預測;
omit- frame-pointer:可能的情況下不產生棧幀;
-O2:以下是-O2在-O1基礎上增加的優化選項:
-falign-functions -falign-jumps -falign-loops -falign-labels
-fcaller-saves -fcrossjumping -fcse-follow-jumps -fcse-skip-blocks
-fdelete-null-pointer-checks -fexpensive-optimizations -fgcse
-fgcse-lm -foptimize-sibling-calls -fpeephole2 -fregmove
-freorder-blocks -freorder-functions -frerun-cse-after-loop
-fsched-interblock -fsched-spec -fschedule-insns
-fschedule-insns2 -fstrict-aliasing -fstrict-overflow -ftree-pre
-ftree-vrp
cpu架構的優化選項,通常是-mcpu(將被取消);-march,-mtune
Debug選項:
在 gcc編譯原始碼時指定-g選項可以產生帶有除錯資訊的目的碼,gcc可以為多個不同平臺上帝不同調試器提供除錯資訊,預設gcc產生的除錯資訊是為 gdb使用的,可以使用-gformat 指定要生成的除錯資訊的格式以提供給其他平臺的其他偵錯程式使用.常用的格式有
-ggdb:生成gdb專 用的除錯資訊,使用最適合的格式(DWARF 2,stabs等)會有一些gdb專用的擴充套件,可能造成其他偵錯程式無法執行.
-gstabs:使用 stabs格式,不包含gdb擴充套件,stabs常用於BSD系統的DBX偵錯程式.
-gcoff:產生COFF格式的除錯資訊,常用於System V下的SDB偵錯程式;
-gxcoff:產生XCOFF格式的除錯資訊,用於IBM的RS/6000下的DBX偵錯程式;
-gdwarf- 2:產生DWARF version2 的格式的除錯資訊,常用於IRIXX6上的DBX偵錯程式.GCC會使用DWARF version3的一些特性.
可 以指定除錯資訊的等級:在指定的除錯格式後面加上等級:
如: -ggdb2 等,0代表不產生除錯資訊.在使用-gdwarf-2時因為最早的格式為-gdwarf2會造成混亂,所以要額外使用一個-glevel來指定除錯資訊的 等級,其他格式選項也可以另外指定等級.
gcc可以使用-p選項指定生成資訊以供porf使用.
GCC常用選項
選項
含義
--help
--target-help
顯示 gcc 幫助說明。‘target-help’是顯示目標機器特定的命令列選項。
--version
顯示 gcc 版本號和版權資訊 。
-o outfile
輸出到指定的檔案。
-x language
指明使用的程式語言。允許的語言包括:c c++ assembler none 。 ‘none’意味著恢復預設行為,即根據檔案的副檔名猜測原始檔的語言。
-v
列印較多資訊,顯示編譯器呼叫的程式。
-###
與 -v 類似,但選項被引號括住,並且不執行命令。
-E
僅作預處理,不進行編譯、彙編和連結。如上圖所示。
-S
僅編譯到組合語言,不進行彙編和連結。如上圖所示。
-c
編譯、彙編到目的碼,不進行連結。如上圖所示。
-pipe
使用管道代替臨時檔案。
-combine
將多個原始檔一次性傳遞給彙編器。
3 其他GCC選項
更多有用的GCC選項:
命令
描述
-l library
-llibrary
進行連結時搜尋名為library的庫。
例子: $ gcc test.c -lm -o test
-Idir
把dir 加入到搜尋標頭檔案的路徑列表中。
例子: $ gcc test.c -I../inc -o test
-Ldir
把dir 加入到搜尋庫檔案的路徑列表中。
例子: $ gcc -I/home/foo -L/home/foo -ltest test.c -o test
-Dname
預定義一個名為name 的巨集,值為1。
例子: $ gcc -DTEST_CONFIG test.c -o test
-Dname =definition
預定義名為name ,值為definition 的巨集。
-ggdb
-ggdblevel
為偵錯程式 gdb 生成除錯資訊。level 可以為1,2,3,預設值為2。
-g
-glevel
生成作業系統本地格式的除錯資訊。-g 和 -ggdb 並不太相同, -g 會生成 gdb 之外的資訊。level 取值同上。
-s
去除可執行檔案中的符號表和重定位資訊。用於減小可執行檔案的大小。
-M
告訴前處理器輸出一個適合make的規則,用於描述各目標檔案的依賴關係。對於每個 原始檔,前處理器輸出 一個make規則,該規則的目標項(target)是原始檔對應的目標檔名,依賴項(dependency)是原始檔中 `#include引用的所有檔案。生成的規則可 以是單行,但如果太長,就用`\'-換行符續成多行。規則 顯示在標準輸出,不產生預處理過的C程式。
-C
告訴前處理器不要丟棄註釋。配合`-E'選項使用。
-P
告訴前處理器不要產生`#line'命令。配合`-E'選項使用。
-static
在支援動態連結的系統上,阻止連線共享庫。該選項在其它系統上 無效。
-nostdlib
不連線系統標準啟動檔案和標準庫檔案,只把指定的檔案傳遞給聯結器。
Warnings
-Wall
會開啟一些很有用的警告選項,建議編譯時加此選項。
-W
-Wextra
列印一些額外的警告資訊。
-w
禁止顯示所有警告資訊。
-Wshadow
當一個區域性變數遮蓋住了另一個區域性變數,或者全域性變數時,給出警告。很有用的選項,建議開啟。 -Wall 並不會開啟此項。
-Wpointer-arith
對函式指標或者void *型別的指標進行算術操作時給出警告。也很有用。 -Wall 並不會開啟此項。
-Wcast-qual
當強制轉化丟掉了型別修飾符時給出警告。 -Wall 並不會開啟此項。
-Waggregate-return
如果定義或呼叫了返回結構體或聯合體的函式,編譯器就發出警告。
-Winline
無論是宣告為 inline 或者是指定了-finline-functions 選項,如果某函式不能內聯,編譯器都將發出警告。如果你的程式碼含有很多 inline 函式的話,這是很有用的選項。
-Werror
把警告當作錯誤。出現任何警告就放棄編譯。
-Wunreachable-code
如果編譯器探測到永遠不會執行到的程式碼,就給出警告。也是比較有用的選項。
-Wcast-align
一旦某個指標型別強制轉換導致目標所需的地址對齊增加時,編譯器就發出警告。
-Wundef
當一個沒有定義的符號出現在 #if 中時,給出警告。
-Wredundant-decls
如果在同一個可見域內某定義多次宣告,編譯器就發出警告,即使這些重複宣告有效並且毫無差別。
Optimization
-O0
禁止編譯器進行優化。預設為此項。
-O
-O1
嘗試優化編譯時間和可執行檔案大小。
-O2
更多的優化,會嘗試幾乎全部的優化功能,但不會進行“空間換時間”的優化方法。
-O3
在 -O2 的基礎上再開啟一些優化選項:-finline-functions, -funswitch-loops 和 -fgcse-after-reload 。
-Os
對生成檔案大小進行優化。它會開啟 -O2 開的全部選項,除了會那些增加檔案大小的。
-finline-functions
把所有簡單的函式內聯進呼叫者。編譯器會探索式地決定哪些函式足夠簡單,值得做這種內聯。
-fstrict-aliasing
施加最強的別名規則(aliasing rules)。
Standard
-ansi
支援符合ANSI標準的C程式。這樣就會關閉GNU C中某些不相容ANSI C的特性。
-std=c89
-iso9899:1990
指明使用標準 ISO C90 作為標準來編譯程式。
-std=c99
-std=iso9899:1999
指明使用標準 ISO C99 作為標準來編譯程式。
-std=c++98
指明使用標準 C++98 作為標準來編譯程式。
-std=gnu9x
-std=gnu99
使用 ISO C99 再加上 GNU 的一些擴充套件。
-fno-asm
不把asm, inline或typeof當作關鍵字,因此這些詞可以用做識別符號。用 __asm__, __inline__和__typeof__能夠替代它們。 `-ansi' 隱含聲明瞭`-fno-asm'。
-fgnu89-inline
告訴編譯器在 C99 模式下看到 inline 函式時使用傳統的 GNU 句法。
C options
-fsigned-char
-funsigned-char
把char定義為有/無符號型別,如同signed char/unsigned char。
-traditional
嘗試支援傳統C編譯器的某些方面。詳見GNU C手冊。
-fno-builtin
-fno-builtin-function
不接受沒有 __builtin_ 字首的函式作為內建函式。
-trigraphs
支援ANSI C的三聯符( trigraphs)。`-ansi'選項隱含聲明瞭此選項。
-fsigned-bitfields
-funsigned-bitfields
如果沒有明確宣告`signed'或`unsigned'修飾符,這些選項用來定義有符號位域或無符號位域。預設情況下,位域是有符號的,因為它們繼承的基本整數型別,如int,是有符號數。
-Wstrict-prototypes
如果函式的宣告或定義沒有指出引數型別,編譯器就發出警告。很有用的警告。
-Wmissing-prototypes
如果沒有預先宣告就定義了全域性函式,編譯器就發出警告。即使函式定義自身提供了函式原形也會產生這個警告。這個選項 的目的是檢查沒有在標頭檔案中宣告的全域性函式。
-Wnested-externs
如果某extern宣告出現在函式內部,編譯器就發出警告。
C++ options
-ffor-scope
從頭開始執行程式,也允許進行重定向。
-fno-rtti
關閉對 dynamic_cast 和 typeid 的支援。如果你不需要這些功能,關閉它會節省一些空間。
-Wctor-dtor-privacy
當一個類沒有用時給出警告。因為建構函式和解構函式會被當作私有的。
-Wnon-virtual-dtor
當一個類有多型性,而又沒有虛解構函式時,發出警告。-Wall會開啟這個選項。
-Wreorder
如果程式碼中的成員變數的初始化順序和它們實際執行時初始化順序不一致,給出警告。
-Wno-deprecated
使用過時的特性時不要給出警告。
-Woverloaded-virtual
如果函式的宣告隱藏住了基類的虛擬函式,就給出警告。
Machine Dependent Options (Intel)
-mtune=cpu-type
為指定型別的 CPU 生成程式碼。cpu-type 可以是:i386,i486,i586,pentium,i686,pentium4 等等。
-msse
-msse2
-mmmx
-mno-sse
-mno-sse2
-mno-mmx
使用或者不使用MMX,SSE,SSE2指令。
-m32
-m64
生成32位/64位機器上的程式碼。
-mpush-args
-mno-push-args
(不)使用 push 指令來進行儲存引數。預設是使用。
-mregparm=num
當傳遞整數引數時,控制所使用暫存器的個數。