徹底的で詳細なg ++警告を有効にするフラグ


122

多くの場合、Cの下gccでは、次の警告フラグのセットから開始します(複数のソースから痛々しくアセンブルされます)。

-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年遅れています)、右足から始めたいと思います。

私の質問は次のとおりです。誰かがC ++のプリコンパイルされた同様の完全な警告フラグのセットを持っていますかg++?(私はそれらの多くが同じになることを知っています。)


69
(それが露骨に決まっていますので、何のgccのニーズについては-Wall)です-Wbloody_everything:-)フラグ
paxdiablo

質問をだましとしてマークすることもできますが、実際に質問に回答したので、最後の編集を回答として使用することもできます。そして、私はそれを
賛成し

4
OPと@paxdiablo:GCCはこの種のことを一貫して拒否しますが、Clangではを介して利用できます-Weverything。私は、Clang ++開発者でさえ、ユーザーがオンにすることについて少し心配していることを読みました。どうやら、それは内部開発での使用のみを目的としていました。しかし、これは意味がありません。-Weverything有効にすることは、おそらく以前は知らなかった、役立つ可能性のある警告を発見するための最良の方法です。
カイルストランド

1
OPと@paxdiablo特定のGCCバージョンの警告の完全なリストを把握する方法があります:github.com/barro/compiler-warnings
Kyle Strand

回答:


138

調べたところ、最大レベルの警告が表示される最小限のインクルードセットが見つかりました。次に、実際に何か問題が発生していることを示しているとは思われない一連の警告をリストから削除しました。私が除外したもののそれぞれが除外された理由についてコメントしました。これは、推奨される警告の最後のセットです。

-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に昇格されます。安全であっても、unsignedまたはunsigned shortに値を割り当てると、潜在的な符号の問題について警告し ます。これは、ほぼすべてのユーザーにとって間違いなく最もオプションの警告です。

  • -Wsign-promo:参照してください-Wsign-conversion

  • -Wswitch-default意味がないように見えます(すべての可能性を明示的に列挙している場合、デフォルトのケースが常に必要なわけではありません)。ただし、この警告をオンにすると、おそらく良いアイデアになる可能性があります。リストされた可能性以外のすべてを明示的に無視したい場合(ただし、他の数値も可能)、次にdefault: break;それを明示的にします。すべての可能性を明示的に列挙する場合、この警告をオンにすると、アサート(false)などを配置して、すべての可能なオプションを実際にカバーしたことを確認できます。これにより、問題のドメインが何であるかを明示し、プログラムでそれを実施できます。ただし、アサート(false)をどこにでも貼り付けることに注意する必要があります。デフォルトのケースで何もしないよりはましですが、assertの場合と同様に、リリースビルドでは機能しません。つまり、絶対に制御できないネットワーク接続やデータベースなどから取得した数値を検証するためにこれに依存することはできません。例外を処理するか、早期に復帰することが、これを処理する最良の方法です(ただし、デフォルトのケースが必要です!)。

  • -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++11GCC 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ステートメントでこれをアクティブにするメカニズムが言語にある場合(列挙への将来の変更が必要なすべての場所で確実に処理されるようにする場合)は便利ですが、「オールオアナッシング」設定には過剰です。

  • -Wunsafe-loop-optimizations偽の警告が多すぎます。これを定期的に適用し、手動で結果を確認すると便利です。例として、(範囲ベースのforループを使用して)ベクトルのすべての要素をループしてそれらに一連の関数を適用すると、コードでこの警告が生成されました。また、const std :: stringのconst配列のコンストラクターに対する警告でもあります(これはユーザーコードのループではありません)。

  • -Wzero-as-null-pointer-constantまた-Wuseless-cast、GCC-4.7のみの警告であり、GCC 4.7への移行時に追加します。

この調査の結果として、gccでいくつかのバグレポート/拡張リクエストを提出したので、うまくいけば、「含めない」リストから「含める」リストにさらに多くの警告を追加できるようになるでしょう。このリストには、このスレッドで言及されているすべての警告が含まれています(さらに、いくつかの追加が考えられます)。この投稿で明示的に言及されていない警告の多くは、私が言及する別の警告の一部として含まれています。この投稿から完全に除外されている警告に気付いた場合は、お知らせください。

編集:いくつかを見逃してしまったようです(今は追加しました)。実際にはhttp://gcc.gnu.orgに 2番目のページがあり、非常によく隠されています。一般的な警告オプションC ++オプション(警告を表示するには、一番下までスクロールしてください)


私は最近、この回答に対する私の調査に基づいて、拡張リクエストを提出しました:gcc.gnu.org/bugzilla/show_bug.cgi?id=53313。警告レベルを作成することで、警告状況を劇的に簡素化します。私の提案では、警告の私の提案セットが意味するであろう-Winfを作成するための追加の提案、-Weverything-と-I-本当に平均それは-この時に、約-w4ある
デヴィッド・ストーン

-Wpaddedの一部を引き起こす拡張リクエストが推奨リストに追加されます:gcc.gnu.org/bugzilla/show_bug.cgi?id
David Stone

-Weffc ++の一部を推奨リストに追加する拡張リクエスト:gcc.gnu.org/bugzilla/show_bug.cgi?id
David Stone

1
@Predelnik:それよりもトリッキーです。-Wswitch-enumスイッチ内のすべての列挙値を明示的に処理しない場合に警告し、明示defaultとしてカウントしません。一方、可能な値をすべて明示的にカバー-Wswitch-defaultしていても、スイッチにdefault大文字小文字の区別がない場合は、警告が表示されます。
David Stone、

2
ところで- 「古いライブラリコード」の-isystem代わりに-Iを使用して、これらすべての誤
検知

39

D'oh、私の元の検索はすべて、警告を抑制する方法に関する投稿の99%を表示しましたが(恐ろしく十分)、このコメントに遭遇しただけです。

クロスチェック:

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

だから、それは良い出発点だと思います。これがだまされていることに気づかなかったが、少なくともそれは深く埋められていた。:-)


1
おそらく、しかし、それはバージョン間で変化するようであり、おそらくサンスポットとRMSの気まぐれであるので、過度に明示的であってもおそらく害はありません。とにかく、それは良い出発点です。
Sdaz MacSkibbons

3
'case OPT_W'の4.5.2のc-opts.c / opts.cのクイックgrepからは、次が欠落しています:厳密なオーバーフロー、undef、厳密なnulセンチネル、正規化、マルチ文字、暗黙的な関数宣言、非推奨、endifラベル、コメントs、組み込みマクロの再定義、より大きい、eqより大きい、abi。それらをリストするコマンドラインオプションがないのはおかしいです。
トニーDelroy

3
-Wallは、人が期待することをしないのは、もっとおかしなことだと思います。しかし、ありがとう、それらのいくつかは非常に便利に見えます!
Sdaz MacSkibbons

1
警告を無効にするのが適切です。結局のところ、それらは「警告」です。もう1つの状況は、複数の警告を有効にするフラグを有効にしたが、それについて選択的にしたい場合です。
タマシュSzelei

1
どのように使用できます-Waggregate-returnか?これにより、使用のたびに警告が表示されますbegin/end()
Flamefire

12

それらの一部は、-Wallまたはにすでに含まれてい-Wextraます。

Cの適切な基本設定は次のとおりです。

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

C ++の場合

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

(いくつかの不快感がある-Werrorため、C ++のスキップ-Weffc++


10
-Werrorは、特定の種類の警告に対して無効にすることができます。次に例を示します。-Werror -Weffc ++ -Wno-error = effc ++
Robert Hensing

2
ansi:Cモードでは、これはと同等-std=c89です。C ++モードでは、と同等-std=c++98です。つまり、他のを指定する場合はstd、使用しないでくださいansi
Sean Breckenridge

2

試す

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

これは迅速かつダーティなスタートであり、間違いなくチューニングが必要です。一つには、あなたの言語に適切な名前でコンパイラを呼び出したとしても(例えばg++ C ++など)でその言語には適用されない警告が表示されます(コンパイラーは手を上げて、警告を削除します)。

もう1つは、で追加した-Werrorことです。警告を修正しないのであれば、なぜ警告をオンにすることに関心があるのですか?リストから警告を出すこともできます。(たとえば-Waggregate-return、C ++ではほとんど使用しません。)

一部の警告は、他のパフォーマンス関連オプション(-Wstack-protector)がないと何もしません。-fdiagnostics-show-optionそしてGCCマニュアルはあなたの友達です。

ところで、いくつかの警告は相互に排他的です。特に-Wtraditional-Wold-style-definition一緒に使用すると-Werror、コンパイルされません。


0

私のClionのCmakeLists.txt

cmake_minimum_required(VERSION 3.13)
project(cpp17)

set(CMAKE_CXX_STANDARD 17)

set(GCC_COVERAGE_COMPILE_FLAGS "-std=c++17 -Wall -Weffc++ -Wno-error=effc++ -pedantic \
 -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-newline-eof  \
-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")


set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )

add_executable(cpp17 main.cpp)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.