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