天天看點

GCC筆記(警告.優化以及調試選項)

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專 用的調試資訊,使用最适合的格式(DWARF2,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會使用DWARFversion3的一些特性.

可以指定調試資訊的等級:在指定的調試格式後面加上等級:

如: -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

将多個源檔案一次性傳遞給彙編器。

更多有用的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

當傳遞整數參數時,控制所使用寄存器的個數。

本文轉自 jiu~ 部落格園部落格,原文連結:http://www.cnblogs.com/jiu0821/p/7305912.html,如需轉載請自行聯系原作者

繼續閱讀