調べたところ、最大レベルの警告が表示される最小限のインクルードセットが見つかりました。次に、実際に何か問題が発生していることを示しているとは思われない一連の警告をリストから削除しました。私が除外したもののそれぞれが除外された理由についてコメントしました。これは、推奨される警告の最後のセットです。
-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++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ステートメントでこれをアクティブにするメカニズムが言語にある場合(列挙への将来の変更が必要なすべての場所で確実に処理されるようにする場合)は便利ですが、「オールオアナッシング」設定には過剰です。
-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 ++オプション(警告を表示するには、一番下までスクロールしてください)
-Wall
)です-Wbloody_everything
:-)フラグ