GCC 2
Section: GNU Tools (1)
Updated: 2003/12/05
預處理器選項(Preprocessor Option)
下列選項針對C預處理器,預處理器用在正式編譯以前,對C 源文件進行某種處理.
如果指定了`-E'選項, GCC只進行預處理工作.下面的某些選項必須和`-E'選項一起才 有意義,因為他們的輸出結果不能用于編譯.
- -include file
- 在處理常規(guī)輸入文件之前,首先處理文件file,其結果是,文件file的內(nèi)容先得到編譯. 命令行上任何`-D'和`-U'選項永遠在`-include file'之前處理, 無論他們在命令行上的順序如何.然而`-include'和`-imacros'選項按書寫順序處理.
- -imacros file
- 在處理常規(guī)輸入文件之前,首先處理文件file,但是忽略輸出結果.由于丟棄了文件file的 輸出內(nèi)容, `-imacros file'選項的唯一效果就是使文件file中的宏定義生效, 可以用于其他輸入文件.在處理`-imacrosfile'選項之前,預處理器首先處理`-D' 和`-U'選項,并不在乎他們在命令行上的順序.然而`-include'和 `-imacros'選項按書寫順序處理.
- -idirafter dir
- 把目錄dir添加到第二包含路徑中.如果某個頭文件在主包含路徑(用`-I'添加的路徑)中沒有 找到,預處理器就搜索第二包含路徑.
- -iprefix prefix
- 指定prefix作為后續(xù)`-iwithprefix'選項的前綴.
- -iwithprefix dir
- 把目錄添加到第二包含路徑中.目錄名由prefix和dir合并而成,這里 prefix被先前的`-iprefix'選項指定.
- -nostdinc
- 不要在標準系統(tǒng)目錄中尋找頭文件.只搜索`-I'選項指定的目錄(以及當前目錄,如果合適).
結合使用`-nostdinc'和`-I-'選項,你可以把包含文件搜索限制在顯式指定的目錄.
- -nostdinc++
- 不要在C++專用標準目錄中尋找頭文件,但是仍然搜索其他標準目錄. (當建立`libg++'時使用 這個選項.)
- -undef
- 不要預定義任何非標準宏. (包括系統(tǒng)結構標志).
- -E
- 僅運行C預處理器.預處理所有指定的C源文件,結果送往標準輸出或指定的輸出文件.
- -C
- 告訴預處理器不要丟棄注釋.配合`-E'選項使用.
- -P
- 告訴預處理器不要產(chǎn)生`#line'命令.配合`-E'選項使用.
- -M [ -MG ]
- 告訴預處理器輸出一個適合make的規(guī)則,用于描述各目標文件的依賴關系.對于每個源文件,預處理器輸出 一個make規(guī)則,該規(guī)則的目標項(target)是源文件對應的目標文件名,依賴項(dependency)是源文件中 `#include引用的所有文件.生成的規(guī)則可以是單行,但如果太長,就用`\'-換行符續(xù)成多行.規(guī)則 顯示在標準輸出,不產(chǎn)生預處理過的C程序.
`-M'隱含了`-E'選項.
`-MG'要求把缺失的頭文件按存在對待,并且假定他們和源程序文件在同一目錄下.必須和 `-M'選項一起用.
- -MM [ -MG ]
- 和`-M'選項類似,但是輸出結果僅涉及用戶頭文件,象這樣`#include file"'.忽略系統(tǒng)頭文件如`#include <file>'.
- -MD
- 和`-M'選項類似,但是把依賴信息輸出在文件中,文件名通過把輸出文件名末尾的`.o'替換為 `.d'產(chǎn)生.同時繼續(xù)指定的編譯工作---`-MD'不象`-M'那樣阻止正常的編譯任務.
Mach的實用工具`md'能夠合并`.d'文件,產(chǎn)生適用于`make'命令的單一的 依賴文件.
- -MMD
- 和`-MD'選項類似,但是輸出結果僅涉及用戶頭文件,忽略系統(tǒng)頭文件.
- -H
- 除了其他普通的操作, GCC顯示引用過的頭文件名.
- -Aquestion(answer)
- 如果預處理器做條件測試,如`#if #question(answer)',該選項可以斷言(Assert) question的答案是answer. -A-'關閉一般用于描述目標機的標準斷言.
- -Dmacro
- 定義宏macro,宏的內(nèi)容定義為字符串`1'.
- -Dmacro=defn
- 定義宏macro的內(nèi)容為defn.命令行上所有的`-D'選項在 `-U'選項之前處理.
- -Umacro
- 取消宏macro. `-U'選項在所有的`-D'選項之后處理,但是優(yōu)先于任何 `-include'或`-imacros'選項.
- -dM
- 告訴預處理器輸出有效的宏定義列表(預處理結束時仍然有效的宏定義).該選項需結合`-E'選項使用.
- -dD
- 告訴預處理器把所有的宏定義傳遞到輸出端,按照出現(xiàn)的順序顯示.
- -dN
- 和`-dD'選項類似,但是忽略宏的參量或內(nèi)容.只在輸出端顯示`#define name.
匯編器選項(ASSEMBLER OPTION)
- -Wa,option
- 把選項option傳遞給匯編器.如果option含有逗號,就在逗號處分割成多個選項.
連接器選項(LINKER OPTION)
下面的選項用于編譯器連接目標文件,輸出可執(zhí)行文件的時候.如果編譯器不進行 連接,他們就毫無意義.
- object-file-name
- 如果某些文件沒有特別明確的后綴a special recognized suffix, GCC就認為他們是目標文件或庫文件. (根據(jù)文件內(nèi)容,連接器能夠區(qū)分目標文件和庫文件).如果GCC執(zhí)行連接操作,這些目標文件將成為連接器的輸入文件.
- -llibrary
- 連接名為library的庫文件.
連接器在標準搜索目錄中尋找這個庫文件,庫文件的真正名字是`liblibrary.a'.連接器會 當做文件名得到準確說明一樣引用這個文件.
搜索目錄除了一些系統(tǒng)標準目錄外,還包括用戶以`-L'選項指定的路徑.
一般說來用這個方法找到的文件是庫文件---即由目標文件組成的歸檔文件(archive file).連接器處理歸檔文件的 方法是:掃描歸檔文件,尋找某些成員,這些成員的符號目前已被引用,不過還沒有被定義.但是,如果連接器找到普通的 目標文件,而不是庫文件,就把這個目標文件按平常方式連接進來.指定`-l'選項和指定文件名的唯一區(qū)別是, `-l選項用`lib'和`.a'把library包裹起來,而且搜索一些目錄.
- -lobjc
- 這個-l選項的特殊形式用于連接Objective C程序.
- -nostartfiles
- 不連接系統(tǒng)標準啟動文件,而標準庫文件仍然正常使用.
- -nostdlib
- 不連接系統(tǒng)標準啟動文件和標準庫文件.只把指定的文件傳遞給連接器.
- -static
- 在支持動態(tài)連接(dynamic linking)的系統(tǒng)上,阻止連接共享庫.該選項在其他系統(tǒng)上無效.
- -shared
- 生成一個共享目標文件,他可以和其他目標文件連接產(chǎn)生可執(zhí)行文件.只有部分系統(tǒng)支持該選項.
- -symbolic
- 建立共享目標文件的時候,把引用綁定到全局符號上.對所有無法解析的引用作出警告(除非用連接編輯選項 `-Xlinker -z -Xlinker defs'取代).只有部分系統(tǒng)支持該選項.
- -Xlinker option
- 把選項option傳遞給連接器.可以用他傳遞系統(tǒng)特定的連接選項, GNU CC無法識別這些選項.
如果需要傳遞攜帶參數(shù)的選項,你必須使用兩次`-Xlinker',一次傳遞選項,另一次傳遞他的參數(shù). 例如,如果傳遞`-assert definitions',你必須寫成`-Xlinker -assert -Xlinker definitions',而不能寫成`-Xlinker "-assert definitions"',因為這樣會把整個 字符串當做一個參數(shù)傳遞,顯然這不是連接器期待的.
- -Wl,option
- 把選項option傳遞給連接器.如果option中含有逗號,就在逗號處分割成多個選項.
- -u symbol
- 使連接器認為取消了symbol的符號定義,從而連接庫模塊以取得定義.你可以使用多個 `-u'選項,各自跟上不同的符號,使得連接器調(diào)入附加的庫模塊.
目錄選項(DIRECTORY OPTION)
下列選項指定搜索路徑,用于查找頭文件,庫文件,或編譯器的某些成員:
- -Idir
- 在頭文件的搜索路徑列表中添加dir 目錄.
- -I-
- 任何在`-I-'前面用`-I'選項指定的搜索路徑只適用于`#include "file"'這種情況;他們不能用來搜索`#include <file>'包含的頭文件.
如果用`-I'選項指定的搜索路徑位于`-I-'選項后面,就可以在這些路徑中搜索所有的 `#include'指令. (一般說來-I選項就是這么用的.)
還有, `-I-'選項能夠阻止當前目錄(存放當前輸入文件的地方)成為搜索`#include "file"'的第一選擇.沒有辦法克服`-I-'選項的這個效應.你可以指定 `-I.'搜索那個目錄,它在調(diào)用編譯器時是當前目錄.這和預處理器的默認行為不完全一樣,但是結果通常 令人滿意.
`-I-'不影響使用系統(tǒng)標準目錄,因此, `-I-'和`-nostdinc'是不同的選項.
- -Ldir
- 在`-l'選項的搜索路徑列表中添加dir目錄.
- -Bprefix
- 這個選項指出在何處尋找可執(zhí)行文件,庫文件,以及編譯器自己的數(shù)據(jù)文件.
編譯器驅動程序需要執(zhí)行某些下面的子程序: `cpp', `cc1' (或C++的 `cc1plus'), `as'和`ld'.他把prefix當作欲執(zhí)行的程序的 前綴,既可以包括也可以不包括`machine/version/'.
對于要運行的子程序,編譯器驅動程序首先試著加上`-B'前綴(如果存在).如果沒有找到文件,或沒有指定 `-B'選項,編譯器接著會試驗兩個標準前綴`/usr/lib/gcc/'和 `/usr/local/lib/gcc-lib/'.如果仍然沒能夠找到所需文件,編譯器就在`PATH'環(huán)境變量 指定的路徑中尋找沒加任何前綴的文件名.
如果有需要,運行時(run-time)支持文件`libgcc.a'也在`-B'前綴的搜索范圍之內(nèi). 如果這里沒有找到,就在上面提到的兩個標準前綴中尋找,僅此而已.如果上述方法沒有找到這個文件,就不連接他了.多數(shù) 情況的多數(shù)機器上, `libgcc.a'并非必不可少.
你可以通過環(huán)境變量GCC_EXEC_PREFIX獲得近似的效果;如果定義了這個變量,其值就和上面說的 一樣用做前綴.如果同時指定了`-B'選項和GCC_EXEC_PREFIX變量,編譯器首先使用 `-B'選項,然后才嘗試環(huán)境變量值.
警告選項(WARNING OPTION)
警告是針對程序結構的診斷信息,程序不一定有錯誤,而是存在風險,或者可能存在 錯誤.
下列選項控制GNU CC產(chǎn)生的警告的數(shù)量和類型:
- -fsyntax-only
- 檢查程序中的語法錯誤,但是不產(chǎn)生輸出信息.
- -w
- 禁止所有警告信息.
- -Wno-import
- 禁止所有關于#import的警告信息.
- -pedantic
- 打開完全服從ANSI C標準所需的全部警告診斷;拒絕接受采用了被禁止的語法擴展的程序.
無論有沒有這個選項,符合ANSI C標準的程序應該能夠被正確編譯(雖然極少數(shù)程序需要`-ansi' 選項).然而,如果沒有這個選項,某些GNU擴展和傳統(tǒng)C特性也得到支持.使用這個選項可以拒絕這些程序.沒有理由 使用這個選項,他存在只是為了滿足一些書呆子(pedant).
對于替選關鍵字(他們以`__'開始和結束) `-pedantic'不會產(chǎn)生警告信息. Pedantic 也不警告跟在__extension__后面的表達式.不過只應該在系統(tǒng)頭文件中使用這種轉義措施,應用程序最好 避免.
- -pedantic-errors
- 該選項和`-pedantic'類似,但是顯示錯誤而不是警告.
- -W
- 對下列事件顯示額外的警告信息:
- *
- 非易變自動變量(nonvolatile automatic variable)可能在調(diào)用longjmp時發(fā)生改變. 這些警告僅在優(yōu)化編譯時發(fā)生.
編譯器只知道對setjmp的調(diào)用,他不可能知道會在哪里調(diào)用longjmp,事實上一個 信號處理例程可以在程序的任何地點調(diào)用他.其結果是,即使程序沒有問題,你也可能會得到警告,因為無法在可能出現(xiàn)問題 的地方調(diào)用longjmp.
- *
- 既可以返回值,也可以不返回值的函數(shù). (缺少結尾的函數(shù)體被看作不返回函數(shù)值)例如,下面的函數(shù)將導致這種警告:
foo (a)
{
if (a > 0)
return a;
}
由于GNU CC不知道某些函數(shù)永不返回(含有abort和longjmp),因此有可能出現(xiàn) 虛假警告.
- *
- 表達式語句或逗號表達式的左側沒有產(chǎn)生作用(side effect).如果要防止這種警告,應該把未使用的表達式強制轉換 為void類型.例如,這樣的表達式`x[i,j]'會導致警告,而`x[(void)i,j]'就不會.
- *
- 無符號數(shù)用`>'或`<='和零做比較.
- -Wimplicit-int
- 警告沒有指定類型的聲明.
- -Wimplicit-function-declaration
- 警告在聲明之前就使用的函數(shù).
- -Wimplicit
- 同-Wimplicit-int和-Wimplicit-function-declaration.
- -Wmain
- 如果把main函數(shù)聲明或定義成奇怪的類型,編譯器就發(fā)出警告.典型情況下,這個函數(shù)用于外部連接, 返回int數(shù)值,不需要參數(shù),或指定兩個參數(shù).
- -Wreturn-type
- 如果函數(shù)定義了返回類型,而默認類型是int型,編譯器就發(fā)出警告.同時警告那些不帶返回值的 return語句,如果他們所屬的函數(shù)并非void類型.
- -Wunused
- 如果某個局部變量除了聲明就沒再使用,或者聲明了靜態(tài)函數(shù)但是沒有定義,或者某條語句的運算結果顯然沒有使用, 編譯器就發(fā)出警告.
- -Wswitch
- 如果某條switch語句的參數(shù)屬于枚舉類型,但是沒有對應的case語句使用枚舉元素,編譯器 就發(fā)出警告. ( default語句的出現(xiàn)能夠防止這個警告.)超出枚舉范圍的case語句同樣會 導致這個警告.
- -Wcomment
- 如果注釋起始序列`/*'出現(xiàn)在注釋中,編譯器就發(fā)出警告.
- -Wtrigraphs
- 警告任何出現(xiàn)的trigraph (假設允許使用他們).
- -Wformat
- 檢查對printf和scanf等函數(shù)的調(diào)用,確認各個參數(shù)類型和格式串中的一致.
- -Wchar-subscripts
- 警告類型是char的數(shù)組下標.這是常見錯誤,程序員經(jīng)常忘記在某些機器上char有符號.
- -Wuninitialized
- 在初始化之前就使用自動變量.
這些警告只可能做優(yōu)化編譯時出現(xiàn),因為他們需要數(shù)據(jù)流信息,只有做優(yōu)化的時候才估算數(shù)據(jù)流信息.如果不指定 `-O'選項,就不會出現(xiàn)這些警告.
這些警告僅針對等候分配寄存器的變量.因此不會發(fā)生在聲明為volatile的變量上面,不會發(fā)生在已經(jīng) 取得地址的變量,或長度不等于1, 2, 4, 8字節(jié)的變量.同樣也不會發(fā)生在結構,聯(lián)合或數(shù)組上面,即使他們在 寄存器中.
注意,如果某個變量只計算了一個從未使用過的值,這里可能不會警告.因為在顯示警告之前,這樣的計算已經(jīng)被 數(shù)據(jù)流分析刪除了.
這些警告作為可選項是因為GNU CC還沒有智能到判別所有的情況,知道有些看上去錯誤的代碼其實是正確的.下面是 一個這樣的例子:
{
int x;
switch (y)
{
case 1: x = 1;
break;
case 2: x = 4;
break;
case 3: x = 5;
}
foo (x);
}
如果y始終是1, 2或3,那么x總會被初始化,但是GNU CC不知道這一點.下面是 另一個普遍案例:
{
int save_y;
if (change_y) save_y = y, y = new_y;
...
if (change_y) y = save_y;
}
這里沒有錯誤,因為只有設置了save_y才使用他.
把所有不返回的函數(shù)定義為volatile可以避免某些似是而非的警告.
- -Wparentheses
- 在某些情況下如果忽略了括號,編譯器就發(fā)出警告.
- -Wtemplate-debugging
- 當在C++程序中使用template的時候,如果調(diào)試(debugging)沒有完全生效,編譯器就發(fā)出警告. (僅用于C++).
- -Wall
- 結合所有上述的`-W'選項.通常我們建議避免這些被警告的用法,我們相信,恰當結合宏的使用能夠 輕易避免這些用法。
剩下的`-W...'選項不包括在`-Wall'中,因為我們認為在必要情況下,這些被編譯器警告 的程序結構,可以合理的用在"干凈的"程序中.
- -Wtraditional
- 如果某些程序結構在傳統(tǒng)C中的表現(xiàn)和ANSI C不同,編譯器就發(fā)出警告.
- *
- 宏參出現(xiàn)在宏體的字符串常量內(nèi)部.傳統(tǒng)C會替換宏參,而ANSI C則視其為常量的一部分.
- *
- 某個函數(shù)在塊(block)中聲明為外部,但在塊結束后才調(diào)用.
- *
- switch語句的操作數(shù)類型是long.
- -Wshadow
- 一旦某個局部變量屏蔽了另一個局部變量,編譯器就發(fā)出警告.
- -Wid-clash-len
- 一旦兩個確定的標識符具有相同的前len個字符,編譯器就發(fā)出警告.他可以協(xié)助你開發(fā)一些將要在某些 過時的,危害大腦的編譯器上編譯的程序.
- -Wpointer-arith
- 任何語句如果依賴于函數(shù)類型的大小(size)或者void類型的大小,編譯器就發(fā)出警告. GNU C為了 便于計算void *指針和函數(shù)指針,就把這些類型的大小定義為1.
- -Wcast-qual
- 一旦某個指針強制類型轉換以便移除類型修飾符時,編譯器就發(fā)出警告.例如,如果把const char * 強制轉換為普通的char *時,警告就會出現(xiàn).
- -Wcast-align
- 一旦某個指針類型強制轉換時,導致目標所需的地址對齊(alignment)增加,編譯器就發(fā)出警告.例如,某些機器上 只能在2或4字節(jié)邊界上訪問整數(shù),如果在這種機型上把char *強制轉換成int *類型, 編譯器就發(fā)出警告.
- -Wwrite-strings
- 規(guī)定字符串常量的類型是const char[length],因此,把這樣的地址復制給 non-const char *指針將產(chǎn)生警告.這些警告能夠幫助你在編譯期間發(fā)現(xiàn)企圖寫入字符串常量 的代碼,但是你必須非常仔細的在聲明和原形中使用const,否則他們只能帶來麻煩;所以我們沒有讓 `-Wall'提供這些警告.
- -Wconversion
- 如果某函數(shù)原形導致的類型轉換和無函數(shù)原形時的類型轉換不同,編譯器就發(fā)出警告.這里包括定點數(shù)和浮點數(shù)的 互相轉換,改變定點數(shù)的寬度或符號,除非他們和缺省聲明(default promotion)相同.
- -Waggregate-return
- 如果定義或調(diào)用了返回結構或聯(lián)合的函數(shù),編譯器就發(fā)出警告. (從語言角度你可以返回一個數(shù)組,然而同樣會 導致警告.)
- -Wstrict-prototypes
- 如果函數(shù)的聲明或定義沒有指出參數(shù)類型,編譯器就發(fā)出警告. (如果函數(shù)的前向引用說明指出了參數(shù)類型,則允許后面 使用舊式風格的函數(shù)定義,而不會產(chǎn)生警告.)
- -Wmissing-prototypes
- 如果沒有預先聲明函數(shù)原形就定義了全局函數(shù),編譯器就發(fā)出警告.即使函數(shù)定義自身提供了函數(shù)原形也會產(chǎn)生這個警告. 他的目的是檢查沒有在頭文件中聲明的全局函數(shù).
- -Wmissing-declarations
- 如果沒有預先聲明就定義了全局函數(shù),編譯器就發(fā)出警告.即使函數(shù)定義自身提供了函數(shù)原形也會產(chǎn)生這個警告.這個選項 的目的是檢查沒有在頭文件中聲明的全局函數(shù).
- -Wredundant-decls
- 如果在同一個可見域某定義多次聲明,編譯器就發(fā)出警告,即使這些重復聲明有效并且毫無差別.
- -Wnested-externs
- 如果某extern聲明出現(xiàn)在函數(shù)內(nèi)部,編譯器就發(fā)出警告.
- -Wenum-clash
- 對于不同枚舉類型之間的轉換發(fā)出警告(僅適用于C++).
- -Wlong-long
- 如果使用了long long 類型就發(fā)出警告.該警告是缺省項.使用`-Wno-long-long' 選項能夠防止這個警告. `-Wlong-long'和`-Wno-long-long'僅在 `-pedantic'之下才起作用.
- -Woverloaded-virtual
- (僅適用于C++.)在繼承類中,虛函數(shù)的定義必須匹配虛函數(shù)在基類中聲明的類型特征(type signature).當 繼承類聲明了某個函數(shù),它可能是個錯誤的嘗試企圖定義一個虛函數(shù),使用這個選項能夠產(chǎn)生警告:就是說,當某個函數(shù)和基類 中的虛函數(shù)同名,但是類型特征不符合基類的任何虛函數(shù),編譯器將發(fā)出警告.
- -Winline
- 如果某函數(shù)不能內(nèi)嵌(inline),無論是聲明為inline或者是指定了-finline-functions 選項,編譯器都將發(fā)出警告.
- -Werror
- 視警告為錯誤;出現(xiàn)任何警告即放棄編譯.