1. 程式人生 > >GCC警告選項及使用

GCC警告選項及使用

不符合ANSI/ISO的原始碼
/*
*  pedant.c - use -ansi, -pedantic or -pedantic-errors
*/
#include <stdio.h>
void main(void)
{
  long long int i = 0l;
  printf("This is a non-conforming c program\n");
}
使用gcc pedant.c -o pedant這個命令時,編譯器會警告main函式的返回型別無效:
$gcc pedant.c -o pedant
pedant.c:In function 'main':
pedant.c:7 warning:return type of 'main' is not 'int'
現在給gcc加上-ansi選項:
$gcc -ansi pedant.c -o pedant
$gcc pedant.c -o pedant
pedant.c: In function 'main'
pedant.c:7 warning: return type of 'main' is not 'int'
gcc再次給出了同樣的警告資訊,並忽略了無效的資料型別.

-ansi,-pedantic以及-pedantic-errors編譯選項並不能保證被編譯的程式的ANSI/ISO相容性,它們僅被用來幫助程式設計師離這個目標更近.

$gcc -Wall pedant.c -o pedant
pedant.c:7: warning: return type of 'main' is not 'int'
pedant.c: In function 'main':
pedant.c:8 warning: unused variable 'i'
-Wall系列選項的另一個極端是-w選項,它能關閉所有的警告資訊。-W{warning}選項的作用是開啟warning所指出的使用者感興趣的特殊警告資訊,比如隱身函式說明(-Wimplicit-function-declaration)或者隱身宣告返回型別的函式(-Wreturn-type).前者的作用在於它提示出定義了一個函式卻沒有事先宣告或者忘記了包含適當的標頭檔案.後者的作用在於指出宣告的函式可能沒有指定它的返回型別,此時預設的返回型別為int.

提示:如果只想檢查語法而實際上不做如何編譯工作,那麼可以呼叫帶有-fsyntax-only引數的GCC.

選項                        說明
-Wcomment                   如果出現了註解巢狀(在第一個/*之後又出現了第二個/*)則發出警告
-Wformat                    如果傳遞給printf及及其相關函式的引數和對應的格式字串中指定的型別不平配則發出警告
-Wmain                      如果main的返回型別不是int或者呼叫main時使用的引數數目不正確則不出警告
-Wparentheses               如果在出現了賦值(例如,(n=10))的地方使用了括號,而那裡根據前後關係推斷應該是比較(例如,(n==100))而非賦值的時候,或者如果括號能夠解決運算優先順序問題的時候,發出警告
-Wswitch                    如果swtich語句少了它的一個或多個列舉值的case分支(只有索引值是enum型別時才適用)則發出警告
-Wunused                    如果宣告的變數沒有使用,或者函式宣告為static型別但卻從未使用,則發出警告
-Wuninitialized             如果使用的自動變數沒有初始化則發出警告
-Wundef                     如果在#if巨集中使用了未定義的變數作判斷則發出警告
-Winline                    如果函式不能被內聯則發出警告
-Wmissing-declarations      如果定義了全域性函式但卻沒有在任何標頭檔案中宣告它,則發出警告
-Wlong-long                 如果使用了long long型別則發出警告
-Werror                     將所有的警告轉變為錯誤


常見的程式設計錯誤:
/*
*  blunder.c - Mistakes caught by -W(warning)
*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  int i, j;
  printf("%c\n", "not a character");  /* -Wformat */
  if(i =10)                          /*-Wparenthesses */
    printf("oops\n");
  if(j !=10)                        /* -Wuninitialized */
    printf("another oops\n");
  /* /**/                            /*-Wcomment */
  no_decl();                          /*-Wmissing-declaration */
  return (EXIT_SUCCESS);
}

void no_decl(void)
{
  printf("no_decl\n");
}
$gcc blunder.c -o blunder
blunder.c:27: warning: type mismatch with previous implicit declaration
blunder.c:21: warning: previous implicit declaration of 'no_decl'
blunder.c:27: warning: 'no_decl' was previously implicitly declared to return 'int'
gcc只發出了和隱式宣告no_decl函式有關的警告.它忽略了其他潛在的錯誤,這些錯誤包括:
.傳遞給printf的引數型別(一個字串)和格式化字串定義的型別(一個字元)不匹配.這會產生一個-Wformat警告.
.變數i和j使用前都沒有初始化.它們中的任何一個都產生-Wuninitialized警告.
.在根據前後關係推斷應該對變數i的值做比較的地方,卻對變數i進行賦值.這應該會產生一個-Wparentheses警告.

.在註釋巢狀開始的地方應該會產生一個-Wcomment警告.

文章轉自:

http://www.blogjava.net/ivanwan/archive/2005/08/04/9338.html

[介紹] 
gcc and g++分別是gnu的c & c++編譯器 gcc/g++在執行編譯工作的時候,總共需要4步 

1.預處理,生成.i的檔案[前處理器cpp] 
2.將預處理後的檔案不轉換成組合語言,生成檔案.s[編譯器egcs] 
3.有彙編變為目的碼(機器程式碼)生成.o的檔案[彙編器as] 
4.連線目的碼,生成可執行程式[連結器ld] 
[引數詳解] 
-x language filename 
  設定檔案所使用的語言,使字尾名無效,對以後的多個有效.也就是根據約定C語言的後 


綴名稱是.c的,而C++的字尾名是.C或者.cpp,如果你很個性,決定你的C程式碼檔案的字尾 
名是.pig 哈哈,那你就要用這個引數,這個引數對他後面的檔名都起作用,除非到了 
下一個引數的使用。 
  可以使用的引數嗎有下面的這些 
  `c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `a 
ssembler-with-cpp'. 
  看到英文,應該可以理解的。 
  例子用法: 
  gcc -x c hello.pig 

-x none filename 
  關掉上一個選項,也就是讓gcc根據檔名字尾,自動識別檔案型別 

  例子用法: 
  gcc -x c hello.pig -x none hello2.c 

-c 
  只啟用預處理,編譯,和彙編,也就是他只把程式做成obj檔案 
  例子用法: 
  gcc -c hello.c 
  他將生成.o的obj檔案 
-S 
  只啟用預處理和編譯,就是指把檔案編譯成為彙編程式碼。 
  例子用法 
  gcc -S hello.c 
  他將生成.s的彙編程式碼,你可以用文字編輯器察看 
-E 
  只啟用預處理,這個不生成檔案,你需要把它重定向到一個輸出檔案裡面. 
  例子用法: 
  gcc -E hello.c > pianoapan.txt 
  gcc -E hello.c | more 
  慢慢看吧,一個hello word 也要與處理成800行的程式碼 
-o 
  制定目標名稱,預設的時候,gcc 編譯出來的檔案是a.out,很難聽,如果你和我有同感 
,改掉它,哈哈 
  例子用法 
  gcc -o hello.exe hello.c (哦,windows用習慣了) 
  gcc -o hello.asm -S hello.c 
-pipe 
  使用管道代替編譯中臨時檔案,在使用非gnu彙編工具的時候,可能有些問題 
  gcc -pipe -o hello.exe hello.c 
-ansi 
  關閉gnu c中與ansi c不相容的特性,啟用ansi c的專有特性(包括禁止一些asm inl 
ine typeof關鍵字,以及UNIX,vax等預處理巨集, 
-fno-asm 
  此選項實現ansi選項的功能的一部分,它禁止將asm,inline和typeof用作關鍵字。 

-fno-strict-prototype 
  只對g++起作用,使用這個選項,g++將對不帶引數的函式,都認為是沒有顯式的對引數 
的個數和型別說明,而不是沒有引數. 
  而gcc無論是否使用這個引數,都將對沒有帶引數的函式,認為城沒有顯式說明的型別 


-fthis-is-varialble 
  就是向傳統c++看齊,可以使用this當一般變數使用. 

-fcond-mismatch 
  允許條件表示式的第二和第三引數型別不匹配,表示式的值將為void型別 

-funsigned-char 
-fno-signed-char 
-fsigned-char 
-fno-unsigned-char 
  這四個引數是對char型別進行設定,決定將char型別設定成unsigned char(前兩個參 
數)或者 signed char(後兩個引數) 

-include file 
  包含某個程式碼,簡單來說,就是便以某個檔案,需要另一個檔案的時候,就可以用它設 
定,功能就相當於在程式碼中使用#include<filename> 
  例子用法: 
  gcc hello.c -include /root/pianopan.h 

-imacros file 
  將file檔案的巨集,擴充套件到gcc/g++的輸入檔案,巨集定義本身並不出現在輸入檔案中 

-Dmacro 
  相當於C語言中的#define macro 

-Dmacro=defn 
  相當於C語言中的#define macro=defn 

-Umacro 
  相當於C語言中的#undef macro 
-undef 
  取消對任何非標準巨集的定義 

-Idir 
  在你是用#include"file"的時候,gcc/g++會先在當前目錄查詢你所制定的標頭檔案,如 
果沒有找到,他回到預設的標頭檔案目錄找,如果使用-I制定了目錄,他 
  回先在你所制定的目錄查詢,然後再按常規的順序去找. 
  對於#include<file>,gcc/g++會到-I制定的目錄查詢,查詢不到,然後將到系統的缺 
省的標頭檔案目錄查詢 

-I- 
  就是取消前一個引數的功能,所以一般在-Idir之後使用 

-idirafter dir 
  在-I的目錄裡面查詢失敗,講到這個目錄裡面查詢. 

-iprefix prefix 
-iwithprefix dir 
  一般一起使用,當-I的目錄查詢失敗,會到prefix+dir下查詢 

-nostdinc 
  使編譯器不再系統預設的標頭檔案目錄裡面找標頭檔案,一般和-I聯合使用,明確限定頭 
檔案的位置 

-nostdin C++ 
  規定不在g++指定的標準路經中搜索,但仍在其他路徑中搜索,.此選項在創libg++庫 
使用 

-C 
  在預處理的時候,不刪除註釋資訊,一般和-E使用,有時候分析程式,用這個很方便的 


-M 
  生成檔案關聯的資訊。包含目標檔案所依賴的所有原始碼你可以用gcc -M hello.c 
來測試一下,很簡單。 

-MM 
  和上面的那個一樣,但是它將忽略由#include<file>造成的依賴關係。 

-MD 
  和-M相同,但是輸出將匯入到.d的檔案裡面 

-MMD 
  和-MM相同,但是輸出將匯入到.d的檔案裡面 

-Wa,option 
  此選項傳遞option給彙編程式;如果option中間有逗號,就將option分成多個選項,然 
後傳遞給會彙編程式 

-Wl.option 
  此選項傳遞option給連線程式;如果option中間有逗號,就將option分成多個選項,然 
後傳遞給會連線程式. 

-llibrary 
  制定編譯的時候使用的庫 
  例子用法 
  gcc -lcurses hello.c 
  使用ncurses庫編譯程式 

-Ldir 
  制定編譯的時候,搜尋庫的路徑。比如你自己的庫,可以用它制定目錄,不然 
  編譯器將只在標準庫的目錄找。這個dir就是目錄的名稱。 

-O0 
-O1 
-O2 
-O3 
  編譯器的優化選項的4個級別,-O0表示沒有優化,-O1為預設值,-O3優化級別最高  

-g 
  只是編譯器,在編譯的時候,產生除錯資訊。 

-gstabs 
  此選項以stabs格式聲稱除錯資訊,但是不包括gdb除錯資訊. 

-gstabs+ 
  此選項以stabs格式聲稱除錯資訊,並且包含僅供gdb使用的額外除錯資訊. 

-ggdb 
  此選項將盡可能的生成gdb的可以使用的除錯資訊. 
-static 
  此選項將禁止使用動態庫,所以,編譯出來的東西,一般都很大,也不需要什麼 
動態連線庫,就可以執行. 
-share 
  此選項將盡量使用動態庫,所以生成檔案比較小,但是需要系統由動態庫. 
-traditional 
  試圖讓編譯器支援傳統的C語言特性