2011-02-23 45 views
87

經常用C gcc下,我將開始與下面設置的警告標誌(來自多個來源的痛苦組裝):標誌,使全面和詳細的G ++警告

-Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast \ 
-Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline -Wundef \ 
-Wnested-externs -Wcast-qual -Wshadow -Wwrite-strings -Wno-unused-parameter \ 
-Wfloat-equal -pedantic -ansi 

我將建立(至少我調試版本)與這組警告並修復我可能可以(通常是所有)的一切,然後只刪除標誌,如果它們不相關或不可修復(幾乎從不是這種情況)。有時,如果我不得不在編譯時離開,我還會添加-Werror

我只是撿起C++(是的,我比時代落後了15年),我想從右腳開始。

我的問題是:是否有人在g++下爲C++預編譯了類似的完整警告標誌集? (我知道很多人是一樣的。)

+54

gcc需要什麼(因爲它決定公然地_lie_關於'-Wall')是一個'-Wbloody_everything'標誌:-) – paxdiablo 2011-02-23 08:22:16

+1

我完全同意! – 2011-02-23 08:23:56

+0

您可以將您的問題標記爲複製,但您也可以將您的上次編輯作爲答案,因爲您實際上已回答了您的問題。我會很高興upvote然後:) – ereOn 2011-02-23 08:34:48

回答

33

D'哦,我所有的原始搜索如何抑制警告(scarily就夠了)打開了99%的職位,但我只是碰到this comment跑,它有這個可愛的標誌集(一些不太相關的):

十字檢查:

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

-g -O -Wall -Weffc++ -pedantic \ 
-pedantic-errors -Wextra -Waggregate-return -Wcast-align \ 
-Wcast-qual -Wconversion \ 
-Wdisabled-optimization \ 
-Werror -Wfloat-equal -Wformat=2 \ 
-Wformat-nonliteral -Wformat-security \ 
-Wformat-y2k \ 
-Wimplicit -Wimport -Winit-self -Winline \ 
-Winvalid-pch \ 
-Wlong-long \ 
-Wmissing-field-initializers -Wmissing-format-attribute \ 
-Wmissing-include-dirs -Wmissing-noreturn \ 
-Wpacked -Wpadded -Wpointer-arith \ 
-Wredundant-decls \ 
-Wshadow -Wstack-protector \ 
-Wstrict-aliasing=2 -Wswitch-default \ 
-Wswitch-enum \ 
-Wunreachable-code -Wunused \ 
-Wunused-parameter \ 
-Wvariadic-macros \ 
-Wwrite-strings 

所以,我認爲這是一個很好的起點。沒有意識到這是一個騙局,但至少它被深埋。 :-)

+3

+1 :)但是,我想知道是否'牆' t已經覆蓋了其中的一些標誌。 – ereOn 2011-02-23 08:40:14

+1

也許,但似乎在版本之間會發生變化,並且可能出現太陽和RMS的突發事件,所以過度顯式可能不會受到傷害。無論如何,這是一個很好的起點。 – 2011-02-23 08:43:49

+3

從4.5.2的c-opts.c/opts快速入門。對於'case OPT_W',你缺少:嚴格溢出,undef,strict nul sentinel,標準化,multichar,隱式函數聲明,不推薦,endif標籤,註釋** s **,內置宏被重新定義,大於,大於eq,abi。令人瘋狂的是,沒有命令行選項來列出它們。 – 2011-02-23 09:03:53

10

其中一些已包含在-Wall-Wextra中。

爲C A良好基礎的設置是:

-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror

和用於C++

-ansi -pedantic -Wall -Wextra -Weffc++

(跳過-Werror用於C++因爲-Weffc++有一些煩惱)

+10

- 對於特定類型的警告,可以禁用錯誤,例如:-Werror -WeffC++ -Wno-error = effC++ – 2012-08-31 14:50:15

100

我去通過並找到了應該得到的最小集合最高級別的警告。然後,我從該列表中刪除了一組警告,我覺得這些警告實際上並不表明發生了不好的事情,或者在真正的構建中使用了太多的誤報。我評論了爲什麼我排除的每個人都被排除在外。這是我的最後一組建議警告:

-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused

可疑的警告,都存在:

  • 我包括-Wno-unused因爲我經常有,我知道我 稍後會使用變量,但還沒有寫入功能。 刪除有關的警告允許我用我的首選樣式 寫偶爾推遲執行的東西。 每隔一段時間就關閉一次,以確保沒有任何東西滑過 。

  • -Wdisabled-optimization看起來像一個強烈的用戶偏好 設置。我只是添加了這個到我的版本(只爲了明顯的原因,優化版本 ),它並沒有改變任何東西,所以它不 似乎是一個特別健談的警告,至少對於我的代碼。 我包含它(即使觸發此警告的代碼不是 一定是錯的),因爲我相信使用我的工具而不是對他們的 。如果gcc告訴我,它不能優化代碼 我寫它的方式,那麼我應該看看重寫它。我懷疑 那個觸發這個警告的代碼可以受益於更多的 模塊化,所以雖然代碼在技術上不是錯誤的 (可能),但它在風格上可能是。

  • -Wfloat-equal發出安全等號比較警告(特別是, 與非計算值-1的比較)。在我的代碼 中,我使用這個例子的一個例子是我有一個float的向量。我經歷了這個向量,並且有一些元素我無法評估,但它們應該是 ,所以我將它們設置爲-1.0f(因爲我的問題只使用 正數,-1不在域中)。我稍後會通過並更新-1.0f值。它不容易適應不同的操作方法。我懷疑大多數人沒有這個 問題,並且浮點數的確切數字的比較是 可能是一個錯誤,所以我將它包含在默認列表中。

  • -Wold-style-cast在我使用的庫代碼中有很多誤報。特別是,網絡中使用的htonl功能家族以及我使用的Rijndael(AES)加密實現具有老式的演員陣容,它警告我。我打算取代這兩個,但我不確定是否有任何其他代碼中,它會抱怨。不過,大多數用戶應該可以默認使用此功能。

  • -Wsign-conversion是一個艱難的(幾乎沒有使 名單)。在我的代碼中打開它會產生大量的警告 (100+)。幾乎所有的人都是無辜的。然而,我一直在 謹慎使用我所不知道的有符號整數,儘管對於我的特定問題域 ,我通常會得到輕微的效率 由於使用無符號值增加了整數 。我犧牲了這個效率,因爲我關心的是 意外地將一個有符號整數提升爲無符號,然後將 除(這是不安全的,不像加法,減法和 乘法)。打開這個警告允許我安全地將 我的大部分變量更改爲無符號類型,並在其他地方的某些 中添加幾個演員。目前有點難以使用,因爲警告 不是那麼聰明。例如,如果您執行unsigned short + (integral constant expression),則該結果隱式提升爲int。如果您將該值分配給 unsignedunsigned short,即使它是安全的,它 會對可能的符號問題發出警告。對於幾乎所有的用戶來說,這絕對是最可選的警告。

  • -Wsign-promo:參見-Wsign-conversion

  • -Wswitch-default似乎毫無意義的(你不要總想,如果你已經明確地列舉所有可能默認 情況下)。但是,打開此警告的 可以強制執行一些可能是好的 的想法。如果您明確要忽略除 以外的所有列出的可能性(但其他數字都是可能的),請將 放入default: break;以使其明確。如果您明確列舉了所有可能性,然後打開此警告將有助於確保 您放置了類似assert(false)的內容,以確保您實際上已覆蓋了所有可能的選項,其中包括 。它可以讓你在 中明確你的問題的領域是什麼,並以編程方式強制執行。 但是,你必須小心,堅持斷言(假) 無處不在。這比默認情況下沒有做什麼好,但通常與斷言 一樣,它在發佈版本中不起作用。在其他 單詞中,您不能依靠它來驗證您獲得的號碼, 說,網絡連接或數據庫沒有絕對控制權。例外情況或提前返回是 句柄的最佳方式(但仍要求您具有默認情況!)。

  • -Werror對我來說很重要。在編譯多個目標的多線程版本中編譯大量 代碼時,很容易出現 警告。將警告轉化爲錯誤可確保我注意到它們。

然後有一組警告沒有包含在上面的列表中,因爲我沒有發現它們是有用的。這是爲什麼我不包括他們在默認列表中的警告和我的意見:

警告是不存在的:不需要

  • -Wabi,因爲我不是從二進制相結合不同的編譯器。無論如何,我試着編譯它,但它並沒有觸發,所以它看起來似乎不必要冗長。

  • -Waggregate-return是不是我認爲是一個錯誤。對於 實例,它會在類的向量 上使用基於範圍的for循環時觸發。返回值優化應該處理任何 負面影響。

  • -Wconversion觸發對這個代碼:short n = 0; n += 2;的 隱式轉換爲INT將導致警告時,它的再轉換 回其目標類型。

  • -Weffc++如果在初始化程序列表中沒有初始化所有數據成員 ,則包含警告。我故意不在許多 個案中這樣做,所以這組警告太混亂而無用。它的 有助於每隔一段時間打開一次,並掃描其他警告, 雖然(如基類的非虛擬析構函數)。這將使 作爲一組警告(如-Wall)而非 單獨發出警告更有用。

  • -Winline缺席,因爲我沒有使用inline關鍵字進行 優化,只是爲了在頭文件中內聯函數定義函數。我不在乎優化程序是否真正將其內聯。這個警告也 抱怨,如果它不能內聯類體 (如一個空的虛擬析構函數)中聲明的函數。

  • -Winvalid-pch缺失,因爲我沒有使用預編譯頭。

  • -Wmissing-format-attribute未使用,因爲我沒有使用gnu 擴展名。 -Wsuggest-attribute和其他幾個

  • 潛在值得注意的是它的缺席是-Wno-long-long,我不需要 。我編譯-std=c++0x-std=c++11在GCC 4.7), 其中包括long long整數類型。那些停留在C++ 98/ 上的C++ 03可能會考慮從警告列表中添加該排除項。

  • -Wnormalized=nfc已經是默認選項,看起來最好是 。

  • -Wpadded偶爾接通以優化 類的佈局,但它不留在因爲並非所有的類有足夠 元件在端部,以除去填充。從理論上講,我可以爲'免費'獲得一些額外的變量,但不值得 維持這個額外的努力(如果我的班級大小發生變化,那麼刪除以前自由變量的 並不容易)。

  • -Wstack-protector不使用,因爲我不使用-fstack-protector

  • -Wstrict-aliasing=3-Wall開啓,是最 準確,但它看起來像1級和2級給予更多的警告。在 理論中,較低的水平是一個「更強」的警告,但它的代價是更多的誤報。我自己的測試代碼在所有3 級別下都清晰地編譯。

  • -Wswitch-enum不是我想要的行爲。我不想明確處理每個switch語句 。如果語言 有一些機制來激活該指定switch語句 (以確保未來無處不處理 ,他們必須枚舉的變化),但它是大材小用「全有或全無這將是有益的「 設置。

  • -Wunsafe-loop-optimizations會導致太多的虛假警告。它 可能會有用的定期應用這一個,並手動驗證 結果。作爲一個例子,它產生在我的代碼這個警告,當我 環繞在在載體中的所有元素到一組函數應用於 它們(使用範圍爲基礎的循環)。它也警告爲 構造常量性病的一個const陣列的::串(這裏,這是在用戶代碼沒有 循環)。

  • -Wzero-as-null-pointer-constant-Wuseless-cast是 GCC-4.7-只有警告,當我轉換到GCC 4.7,我會添加。

我在海合會提出了幾個錯誤報告/增強請求爲一些這方面研究的結果,所以希望我能最終增加更多的警告從「不包括」列表到「包含」列表。這個列表包括了這個線程中提到的所有警告(加上我認爲一些額外的)。本文中未明確提及的許多警告都包含在我提到的另一個警告中。如果有人注意到這篇文章中排除的任何警告,請告訴我。

編輯:它看起來像我錯過了幾個(我現在已經加入)。實際上在http://gcc.gnu.org處有第二個頁面,它隱藏得很好。 General warning optionsC++ options (scroll down to the bottom for warnings)

+0

我最近根據我對此答案的研究提交了一個增強請求:http://gcc.gnu.org/ Bugzilla的/ show_bug.cgi?ID = 53313。這將通過創建警告級別來顯着簡化警告情況。在我的建議中,我建議的一組警告大約是-W4,另外還有一個建議是要創建-Winf,這意味着 - 萬物 - 而且我真的意味着它這次 – 2012-05-10 22:02:51

+0

增強請求會導致部分-Wpadded添加到推薦列表中:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53514 – 2012-05-29 01:54:04

+0

增強請求會導致部分-WeffC++添加到推薦列表中:http:// gcc.gnu.org/bugzilla/show_bug.cgi?id=16166 – 2012-05-29 02:15:40

2

嘗試

export CFLAGS="`gcc --help=warnings | grep '\-W' | awk '{print $1 \" \"}' | 
sort | uniq` -pedantic -fdiagnostic-show-option -Werror" 

這是一個快速和骯髒的開始,這肯定會需要一些調整;一方面,即使您使用適合您的語言的名稱(例如,用於C++的g ++)來調用編譯器,您也會收到不適用於該語言的警告(並且編譯器會拋出它的手並拒絕繼續直到你刪除警告)。

另一件事是我加入了-Werror,因爲如果你沒有修復警告,你爲什麼關心打開它們?您也可以從列表中取出警告(例如,我幾乎從不使用C++編寫的-Waggregate-return)。

如果沒有其他性能相關選項,某些警告將不會執行任何操作(-Wstack-protector)。 -fdiagnostic-show-option和GCC手冊是你的朋友。

順便說一句,一些警告是互斥的;特別是使用-Wtraditional-Wold-style-definition以及-Werror,將不會編譯。

+0

請注意,選項是'-fdiagnostics-show-option'(不是'-fdiagnostic-show-option ')。我試着編輯帖子來解決這個問題,但是stackoverflow抱怨編輯必須至少有6個字符(!)。 – 2017-01-17 22:28:38