1. 程式人生 > >gcc 警告選項

gcc 警告選項

p, li { white-space: pre-wrap; }

警告選項

警告是針對程式結構的診斷資訊,程式不一定有錯誤,而是存在風險,或者可能存在錯誤.

下列選項控制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.

*

既可以返回值,也可以不返回值的函式. (缺少結尾的函式體被看作不返回函式值)例如,下面的函式將導致這種警告:

foo (a)

{

if (a > 0)

return 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函式宣告或定義成奇怪的型別,編譯器就發出警告.典型情況下,這個

函式用於外部連線, 返回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還沒有智慧到判別所有的情況,知道有些看上

去錯誤的程式碼其實是正確的.下面是 一個這樣的例子:

{

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才使用他.

把所有不返回的函式定義為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

如果函式的宣告或定義沒有指出引數型別,編譯器就發出警告. (如果函式的前向引用說明指出了引數型別,則允許後面 使用舊式風格的函式定義,而不會產生警告.)

-Wmissing-prototypes

如果沒有預先宣告函式原形就定義了全域性函式,編譯器就發出警告.即使函式定義自身提供了函式原形也會產生這個警告. 他的目的是檢查沒有在標頭檔案中宣告的全域性函式.

-Wmissing-declarations

如果沒有預先宣告就定義了全域性函式,編譯器就發出警告.即使函式定義自身提供了函式原形也會產生這個警告.這個選項 的目的是檢查沒有在標頭檔案中宣告的全域性函式.

-Wredundant-decls

如果在同一個可見域某定義多次宣告,編譯器就發出警告,即使這些重複宣告有效並且毫無差別.

-Wnested-externs

如果某extern宣告出現在函式內部,編譯器就發出警告.

-Wenum-clash

對於不同列舉型別之間的轉換髮出警告(僅適用於C++).

-Wlong-long

如果使用了long long 型別就發出警告.該警告是預設項.使用`-Wno-long-long' 選項能夠防止這個警告. `-Wlong-long'和`-Wno-long-long'僅在 `-pedantic'之下才起作用.

-Woverloaded-virtual

(僅適用於C++.)在繼承類中,虛擬函式的定義必須匹配虛擬函式在基類中宣告的型別特徵(type signature).當 繼承類聲明瞭某個函式,它可能是個錯誤的嘗試企圖定義一個虛擬函式,使用這個選項能夠產生警告:就是說,當某個函式和基類 中的虛擬函式同名,但是型別特徵不符合基類的任何虛擬函式,編譯器將發出警告.

-Winline

如果某函式不能內嵌(inline),無論是宣告為inline或者是指定了-finline-functions 選項,編譯器都將發出警告.

-Werror

視警告為錯誤;出現任何警告即放棄編譯.

轉自: