GCC 前處理器選項
前處理器選項(Preprocessor Option)
下列選項針對C前處理器,前處理器用在正式編譯以前,對C 原始檔進行某種處理.如果指定了`-E'選項, GCC只進行預處理工作.下面的某些選項必須和`-E'選項一起才 有意義,因為他們的輸出結果不能用於編譯.
- -include file
- 在處理常規輸入檔案之前,首先處理檔案file,其結果是,檔案file的內容先得到編譯. 命令列上任何`-D
- -imacros file
- 在處理常規輸入檔案之前,首先處理檔案file,但是忽略輸出結果.由於丟棄了檔案file的 輸出內容, `-imacros file'選項的唯一效果就是使檔案file中的巨集定義生效, 可以用於其他輸入檔案.在處理`-imacrosfile'選項之前,前處理器首先處理`-D' 和`-U'選項,並不在乎他們在命令列上的順序.然而`-include'和 `-imacros'選項按書寫順序處理
- -idirafter dir
- 把目錄dir新增到第二包含路徑中.如果某個標頭檔案在主包含路徑(用`-I'新增的路徑)中沒有 找到,前處理器就搜尋第二包含路徑.
- -iprefix prefix
- 指定prefix作為後續`-iwithprefix'選項的字首.
- -iwithprefix dir
- 把目錄新增到第二包含路徑中.目錄名由prefix和dir合併而成,這裡 prefix被先前的`-iprefix'選項指定.
- -nostdinc
- 不要在標準系統目錄中尋找標頭檔案.只搜尋`-I'選項指定的目錄(以及當前目錄
結合使用`-nostdinc'和`-I-'選項,你可以把包含檔案搜尋限制在顯式指定的目錄.
- -nostdinc++
- 不要在C++專用標準目錄中尋找標頭檔案,但是仍然搜尋其他標準目錄. (當建立`libg++'時使用 這個選項.)
- -undef
- 不要預定義任何非標準巨集. (包括系統結構標誌).
- -E
- 僅執行C前處理器.預處理所有指定的C原始檔,結果送往標準輸出或指定的輸出檔案.
- -C
- 告訴前處理器不要丟棄註釋.配合`-E'選項使用.
- -P
- 告訴前處理器不要產生`#line'命令.配合`-E'選項使用.
- -M [ -MG ]
- 告訴前處理器輸出一個適合make的規則,用於描述各目標檔案的依賴關係.對於每個原始檔,前處理器輸出 一個make規則,該規則的目標項(target)是原始檔對應的目標檔名,依賴項(dependency)是原始檔中 `#include引用的所有檔案.生成的規則可以是單行,但如果太長,就用`/'-換行符續成多行.規則 顯示在標準輸出,不產生預處理過的C程式.
`-M'隱含了`-E'選項.
`-MG'要求把缺失的標頭檔案按存在對待,並且假定他們和源程式檔案在同一目錄下.必須和 `-M'選項一起用.
- -MM [ -MG ]
- 和`-M'選項類似,但是輸出結果僅涉及使用者標頭檔案,象這樣`#include file"'.忽略系統標頭檔案如`#include <file>'.
- -MD
- 和`-M'選項類似,但是把依賴資訊輸出在檔案中,檔名通過把輸出檔名末尾的`.o'替換為 `.d'產生.同時繼續指定的編譯工作---`-MD'不象`-M'那樣阻止正常的編譯任務.
Mach的實用工具`md'能夠合併`.d'檔案,產生適用於`make'命令的單一的 依賴檔案.
- -MMD
- 和`-MD'選項類似,但是輸出結果僅涉及使用者標頭檔案,忽略系統標頭檔案.
- -H
- 除了其他普通的操作, GCC顯示引用過的標頭檔案名.
- -Aquestion(answer)
- 如果前處理器做條件測試,如`#if #question(answer)',該選項可以斷言(Assert) question的答案是answer. -A-'關閉一般用於描述目標機的標準斷言.
- -Dmacro
- 定義巨集macro,巨集的內容定義為字串`1'.
- -Dmacro=defn
- 定義巨集macro的內容為defn.命令列上所有的`-D'選項在 `-U'選項之前處理.
- -Umacro
- 取消巨集macro. `-U'選項在所有的`-D'選項之後處理,但是優先於任何 `-include'或`-imacros'選項.
- -dM
- 告訴前處理器輸出有效的巨集定義列表(預處理結束時仍然有效的巨集定義).該選項需結合`-E'選項使用.
- -dD
- 告訴前處理器把所有的巨集定義傳遞到輸出端,按照出現的順序顯示.
- -dN
- 和`-dD'選項類似,但是忽略巨集的參量或內容.只在輸出端顯示`#define name.
彙編器選項(ASSEMBLER OPTION)
- -Wa,option
- 把選項option傳遞給彙編器.如果option含有逗號,就在逗號處分割成多個選項.
聯結器選項(LINKER OPTION)
下面的選項用於編譯器連線目標檔案,輸出可執行檔案的時候.如果編譯器不進行 連線,他們就毫無意義.- object-file-name
- 如果某些檔案沒有特別明確的字尾a special recognized suffix, GCC就認為他們是目標檔案或庫檔案. (根據檔案內容,聯結器能夠區分目標檔案和庫檔案).如果GCC執行連線操作,這些目標檔案將成為聯結器的輸入檔案.
- -llibrary
- 連線名為library的庫檔案.
聯結器在標準搜尋目錄中尋找這個庫檔案,庫檔案的真正名字是`liblibrary.a'.聯結器會 當做檔名得到準確說明一樣引用這個檔案.
搜尋目錄除了一些系統標準目錄外,還包括使用者以`-L'選項指定的路徑.
一般說來用這個方法找到的檔案是庫檔案---即由目標檔案組成的歸檔檔案(archive file).聯結器處理歸檔檔案的 方法是:掃描歸檔檔案,尋找某些成員,這些成員的符號目前已被引用,不過還沒有被定義.但是,如果聯結器找到普通的 目標檔案,而不是庫檔案,就把這個目標檔案按平常方式連線進來.指定`-l'選項和指定檔名的唯一區別是, `-l選項用`lib'和`.a'把library包裹起來,而且搜尋一些目錄.
- -lobjc
- 這個-l選項的特殊形式用於連線Objective C程式.
- -nostartfiles
- 不連線系統標準啟動檔案,而標準庫檔案仍然正常使用.
- -nostdlib
- 不連線系統標準啟動檔案和標準庫檔案.只把指定的檔案傳遞給聯結器.
- -static
- 在支援動態連線(dynamic linking)的系統上,阻止連線共享庫.該選項在其他系統上無效.
- -shared
- 生成一個共享目標檔案,他可以和其他目標檔案連線產生可執行檔案.只有部分系統支援該選項.
- -symbolic
- 建立共享目標檔案的時候,把引用繫結到全域性符號上.對所有無法解析的引用作出警告(除非用連線編輯選項 `-Xlinker -z -Xlinker defs'取代).只有部分系統支援該選項.
- -Xlinker option
- 把選項option傳遞給聯結器.可以用他傳遞系統特定的連線選項, 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-'不影響使用系統標準目錄,因此, `-I-'和`-nostdinc'是不同的選項.
- -Ldir
- 在`-l'選項的搜尋路徑列表中新增dir目錄.
- -Bprefix
- 這個選項指出在何處尋找可執行檔案,庫檔案,以及編譯器自己的資料檔案.
編譯器驅動程式需要執行某些下面的子程式: `cpp', `cc1' (或C++的 `cc1plus'), `as'和`ld'.他把prefix當作欲執行的程式的 字首,既可以包括也可以不包括`machine/version/'.
對於要執行的子程式,編譯器驅動程式首先試著加上`-B'字首(如果存在).如果沒有找到檔案,或沒有指定 `-B'選項,編譯器接著會試驗兩個標準字首`/usr/lib/gcc/'和 `/usr/local/lib/gcc-lib/'.如果仍然沒能夠找到所需檔案,編譯器就在`PATH'環境變數 指定的路徑中尋找沒加任何字首的檔名.
如果有需要,執行時(run-time)支援檔案`libgcc.a'也在`-B'字首的搜尋範圍之內. 如果這裡沒有找到,就在上面提到的兩個標準字首中尋找,僅此而已.如果上述方法沒有找到這個檔案,就不連線他了.多數 情況的多數機器上, `libgcc.a'並非必不可少.
你可以通過環境變數GCC_EXEC_PREFIX獲得近似的效果;如果定義了這個變數,其值就和上面說的 一樣用做字首.如果同時指定了`-B'選項和GCC_EXEC_PREFIX變數,編譯器首先使用 `-B'選項,然後才嘗試環境變數值.
警告選項(WARNING OPTION)
警告是針對程式結構的診斷資訊,程式不一定有錯誤,而是存在風險,或者可能存在 錯誤.下列選項控制GNU CC產生的警告的數量和型別:
- -fsyntax-only
- 檢查程式中的語法錯誤,但是不產生輸出資訊.
- -w
- 禁止所有警告資訊.
- -Wno-import
- 禁止所有關於#import的警告資訊.
- -pedantic
- 開啟完全服從ANSI C標準所需的全部警告診斷;拒絕接受採用了被禁止的語法擴充套件的程式.
無論有沒有這個選項,符合ANSI C標準的程式應該能夠被正確編譯(雖然極少數程式需要`-ansi' 選項).然而,如果沒有這個選項,某些GNU擴充套件和傳統C特性也得到支援.使用這個選項可以拒絕這些程式.沒有理由 使用這個選項,他存在只是為了滿足一些書呆子(pedant).
對於替選關鍵字(他們以`__'開始和結束) `-pedantic'不會產生警告資訊. Pedantic 也不警告跟在__extension__後面的表示式.不過只應該在系統標頭檔案中使用這種轉義措施,應用程式最好 避免.
- -pedantic-errors
- 該選項和`-pedantic'類似,但是顯示錯誤而不是警告.
- -W
- 對下列事件顯示額外的警告資訊:
- *
- 非易變自動變數(nonvolatile automatic variable)可能在呼叫longjmp時發生改變. 這些警告僅在優化編譯時發生.
編譯器只知道對setjmp的呼叫,他不可能知道會在哪裡呼叫longjmp,事實上一個 訊號處理例程可以在程式的任何地點呼叫他.其結果是,即使程式沒有問題,你也可能會得到警告,因為無法在可能出現問題 的地方呼叫longjmp.
- *
- 既可以返回值,也可以不返回值的函式. (缺少結尾的函式體被看作不返回函式值)例如,下面的函式將導致這種警告: 由於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函式宣告或定義成奇怪的型別,編譯器就發出警告.典型情況下,這個函式用於外部連線, 返回int數值,不需要引數,或指定兩個引數.
- -Wreturn-type
- 如果函式定義了返回型別,而預設型別是int型,編譯器就發出警告.同時警告那些不帶返回值的 return語句,如果他們所屬的函式並非void型別.
- -Wunused
- 如果某個區域性變數除了宣告就沒再使用,或者聲明瞭靜態函式但是沒有定義,或者某條語句的運算結果顯然沒有使用, 編譯器就發出警告.
- -Wswitch
- 如果某條switch語句的引數屬於列舉型別,但是沒有對應的case語句使用列舉元素,編譯器 就發出警告. ( default語句的出現能夠防止這個警告.)超出列舉範圍的case語句同樣會 導致這個警告.
- -Wcomment
- 如果註釋起始序列`/*'出現在註釋中,編譯器就發出警告.
- -Wtrigraphs
- 警告任何出現的trigraph (假設允許使用他們).
- -Wformat
- 檢查對printf和scanf等函式的呼叫,確認各個引數型別和格式串中的一致.
- -Wchar-subscripts
- 警告型別是char的陣列下標.這是常見錯誤,程式設計師經常忘記在某些機器上char有符號.
- -Wuninitialized
- 在初始化之前就使用自動變數.
這些警告只可能做優化編譯時出現,因為他們需要資料流資訊,只有做優化的時候才估算資料流資訊.如果不指定 `-O'選項,就不會出現這些警告.
這些警告僅針對等候分配暫存器的變數.因此不會發生在宣告為volatile的變數上面,不會發生在已經 取得地址的變數,或長度不等於1, 2, 4, 8位元組的變數.同樣也不會發生在結構,聯合或陣列上面,即使他們在 暫存器中.
注意,如果某個變數只計算了一個從未使用過的值,這裡可能不會警告.因為在顯示警告之前,這樣的計算已經被 資料流分析刪除了.
這些警告作為可選項是因為GNU CC還沒有智慧到判別所有的情況,知道有些看上去錯誤的程式碼其實是正確的.下面是 一個這樣的例子:
如果y始終是1, 2或3,那麼x總會被初始化,但是GNU CC不知道這一點.下面是 另一個普遍案例: 這裡沒有錯誤,因為只有設定了save_y才使用他.把所有不返回的函式定義為volatile可以避免某些似是而非的警告.
- -Wparentheses
- 在某些情況下如果忽略了括號,編譯器就發出警告.
- -Wtemplate-debugging
- 當在C++程式中使用template的時候,如果除錯(debugging)沒有完全生效,編譯器就發出警告. (僅用於C++).
- -Wall
- 結合所有上述的`-W'選項.通常我們建議避免這些被警告的用法,我們相信,恰當結合巨集的使用能夠 輕易避免這些用法。
剩下的`-W...'選項不包括在`-Wall'中,因為我們認為在必要情況下,這些被編譯器警告 的程式結構,可以合理的用在"乾淨的"程式中.
- -Wtraditional
- 如果某些程式結構在傳統C中的表現和ANSI C不同,編譯器就發出警告.
- *
- 巨集參出現在巨集體的字串常量內部.傳統C會替換巨集參,而ANSI C則視其為常量的一部分.
- *
- 某個函式在塊(block)中宣告為外部,但在塊結束後才呼叫.
- *
- switch語句的運算元型別是long.
- -Wshadow
- 一旦某個區域性變數遮蔽了另一個區域性變數,編譯器就發出警告.
- -Wid-clash-len
- 一旦兩個確定的識別符號具有相同的前len個字元,編譯器就發出警告.他可以協助你開發一些將要在某些 過時的,危害大腦的編譯器上編譯的程式.
- -Wpointer-arith
- 任何語句如果依賴於函式型別的大小(size)或者void型別的大小,編譯器就發出警告. GNU C為了 便於計算void *指標和函式指標,就把這些型別的大小定義為1.
- -Wcast-qual
- 一旦某個指標強制型別轉換以便移除型別修飾符時,編譯器就發出警告.例如,如果把const char * 強制轉換為普通的char *時,警告就會出現.
- -Wcast-align
- 一旦某個指標型別強制轉換時,導致目標所需的地址對齊(alignment)增加,編譯器就發出警告.例如,某些機器上 只能在2或4位元組邊界上訪問整數,如果在這種機型上把char *強制轉換成int *型別, 編譯器就發出警告.
- -Wwrite-strings
- 規定字串常量的型別是const char[length],因此,把這樣的地址複製給 non-const char *指標將產生警告.這些警告能夠幫助你在編譯期間發現企圖寫入字串常量 的程式碼,但是你必須非常仔細的在宣告和原形中使用const,否則他們只能帶來麻煩;所以我們沒有讓 `-Wall'提供這些警告.
- -Wconversion
- 如果某函式原形導致的型別轉換和無函式原形時的型別轉換不同,編譯器就發出警告.這裡包括定點數和浮點數的 互相轉換,改變定點數的寬度或符號,除非他們和預設宣告(default promotion)相同.
- -Waggregate-return
- 如果定義或呼叫了返回結構或聯合的函式,編譯器就發出警告. (從語言角度你可以返回一個數組,然而同樣會 導致警告.)
- -Wstrict-prototypes
- 如果函式的宣告或定義沒有指出引數型別,編譯器就發出警告