コンテキストについては、私はGoogleで働いているClang開発者です。Googleでは、Clangの診断を(本質的に)すべてのC ++開発者に公開し、Clangの警告もエラーとして扱います。Clangの開発者であり、Clangの診断の大規模なユーザーの1つでもあるので、これらのフラグとその使用方法に光を当てるつもりです。ここで説明するものはすべてClangに一般的に適用可能であり、C、C ++、またはObjective-Cに固有のものではないことに注意してください。
TL; DRバージョン:開発中の新しいコードを少なくとも使用-Wall
し-Werror
てください。私たち(コンパイラ開発者)は、正当な理由で警告をここに追加します:彼らはバグを見つけます。バグをキャッチする警告を見つけた場合は、同様にオンにします。-Wextra
ここでたくさんの良い候補者を探してみてください。それらのいずれかがあなたにとって有益であるためにうるさすぎる場合は、バグを報告してください。「明らかな」バグを含むコードを作成しても、コンパイラがそれについて警告しなかった場合は、バグを提出してください。
長いバージョンになりました。警告フラグのグループ化に関する最初の背景。Clangには(そしてGCCには限られた範囲で)多くの警告の「グループ化」があります。この議論に関連するもの:
- デフォルトで:これらの警告は、明示的に無効にしない限り常にオンです。
-Wall
:これらは、開発者がその価値と低い誤検知率の両方に高い信頼を持っているという警告です。
-Wextra
:これらは、価値があり健全であると考えられている警告です(つまり、バグではありません)が、偽陽性率が高いか、一般的な哲学的反対がある場合があります。
-Weverything
:これは、
Clangのすべての警告を文字通り有効にする非常識なグループです。コードでこれを使用しないでください。それは厳密にClang開発者か、どんな警告が存在するかを調査することを意図しています。
上記の2つの主要な基準があり、Clangで警告がどこに送られるかをガイドし、これらが本当に意味することを明確にしましょう。1つ目は、特定の警告発生の潜在的な
値です。これは、警告が発生
し、コードの問題を正しく識別する場合に、ユーザー(開発者)に期待される利点です。
2番目の基準は、誤検知レポートのアイデアです。これらは、コードに対して警告が発せられる状況ですが、引用されている潜在的な問題は、プログラムのコンテキストまたはその他の制約のために実際には発生しません。警告されたコードは実際には正しく動作しています。これらは、そのコードパターンで警告が発動されることを意図していなかった場合、特に悪いです。代わりに、警告の実装に欠陥があるため、警告が発生します。
Clangの警告の場合、値はスタイル、好み、コーディング規約ではなく、正確さの観点から求められます。これにより、使用可能な警告のセットが制限{}
され、if
ステートメントの本文でsが使用されていない場合は常に警告などの頻繁に要求される警告が除外されます。Clangは偽陽性にも非常に不寛容です。他のほとんどのコンパイラとは異なり、コンストラクトの正確なスペル、余分な「()」、キャスト、プリプロセッサマクロの有無など、誤検知を排除するために、信じられないほど多様な情報ソースを使用します!
次に、Clangからの実際の警告の例をいくつか見て、それらがどのように分類されるかを見てみましょう。まず、デフォルトの警告:
% nl x.cc
1 class C { const int x; };
% clang -fsyntax-only x.cc
x.cc:1:7: warning: class 'C' does not declare any constructor to initialize its non-modifiable members
class C { const int x; };
^
x.cc:1:21: note: const member 'x' will never be initialized
class C { const int x; };
^
1 warning generated.
ここでは、この警告を取得するのにフラグは必要ありません。理由は、これはコードが決して正しいとは限らず、警告値が高くなり、警告はClangがこのバケットに入ることを証明できるコードでのみ発生し、誤検知率がゼロになることです。
% nl x2.cc
1 int f(int x_) {
2 int x = x;
3 return x;
4 }
% clang -fsyntax-only -Wall x2.cc
x2.cc:2:11: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]
int x = x;
~ ^
1 warning generated.
Clangでは、-Wall
この警告にフラグが必要です。その理由は、初期化されていない値を意図的に生成することを警告しているコードパターンを(善悪を問わず)使用している重要なコードがそこにあるためです。哲学的には、これには何の意味もありませんが、他の多くの人は意見が異なり、この意見の違いの現実が-Wall
旗の下で警告を駆り立てるもの
です。依然として非常に高い価値と非常に低い
誤検知率を持っていますが、一部のコードベースでは、それは非スターターです。
% nl x3.cc
1 void g(int x);
2 void f(int arr[], unsigned int size) {
3 for (int i = 0; i < size; ++i)
4 g(arr[i]);
5 }
% clang -fsyntax-only -Wextra x3.cc
x3.cc:3:21: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
for (int i = 0; i < size; ++i)
~ ^ ~~~~
1 warning generated.
この警告には-Wextra
フラグが必要です。その理由は、
比較の符号の不一致が非常に一般的である非常に大きなコードベースがあるためです。この警告にはいくつかのバグがありますが、ユーザーが書いたときにコードがバグになる可能性は平均してかなり低いです。その結果、非常に高い偽陽性率が得られます。プログラムのバグが原因奇妙なプロモーションルールにがある場合しかし、それはこの警告をすることが多い、非常に微妙な
バグがとき、それはフラグが比較的高い持っている価値を。結果として、Clangはそれを提供し、フラグの下で公開します。
通常、警告は-Wextra
フラグの外側では長く続きません。Clangは、通常の使用とテストが行われない警告を実装しないように非常に努力しています。によってオンにされる追加の警告-Weverything
は、通常、アクティブな開発中またはアクティブなバグがある警告です。それらは修正され、適切なフラグの下に配置されるか、削除する必要があります。
これらがClangでどのように機能するかを理解できたので、元の質問に戻りましょう。開発のためにどの警告をオンにする必要がありますか?残念なことに、答えはそれによって異なります。次の質問を考慮して、状況に最も適した警告を判断してください。
- すべてのコードを制御できますか、それとも外部のコードですか?
- あなたの目標は何ですか?バグをキャッチする、またはより良いコードを書く?
- あなたの偽陽性耐性は何ですか?警告を沈黙させるために、定期的に追加のコードを作成してもよろしいですか?
何よりもまず、コードを制御しない場合は、追加の警告を表示しないでください。オフにする準備をしてください。世界には多くの不正なコードがあり、すべてを修正できるとは限りません。それは大丈夫です。制御するコードに努力を集中させる方法を見つけるために働きます。
次に、警告から何を望むかを考えます。これは人によって異なります。Clangは、重大なバグ、またはバグ率が非常に高いことを示す長い歴史的な先例があるコードパターンに関するオプションなしで警告しようとします。-Wall
Clang開発者がC ++コードで観察した最も一般的な間違いを見つけることを目的とした、より積極的な一連の警告を取得できるようになります。しかし、これらの両方で、
偽陽性率は非常に低いままでなければなりません。
最後に、ターンごとに* 誤検出 *を完全に黙らせたい場合は、に進み-Wextra
ます。多くの実際のバグをキャッチしているが、愚かな、または無意味な誤検知がある警告に気付いた場合は、バグを提出してください。私たちは常にに存在するバグ検出ロジックのより多くをもたらすための方法を見つけるために取り組んでいる-Wextra
に-Wall
我々は偽陽性を避けることができる場所を。
多くの人は、これらのオプションはどれもそれらにぴったりではないことに気付くでしょう。Googleでは、-Wall
既存のコードの多くが警告に違反しているため、いくつかの警告をオフにしました。また-Wall
、特に価値が高いため、によって有効にされていなくても、いくつかの警告を明示的にオンにしました。走行距離はさまざまですが、同様の方法で変わる可能性があります。多くの場合、すべてではなく、いくつかの重要な警告を有効にする方がはるかに優れています
-Wextra
。
私は励ます皆をオンにする-Wall
任意の非レガシーコードのために。新しいコードの場合、ここでの警告はほとんど常に価値があり、実際にコード開発の経験を改善します。逆に、を超えてフラグを有効にしないことを皆に勧めます
-Wextra
。Clangの警告が-Wextra
含まれていませんが、それがあなたにとってまったく価値があることがわかった場合は、バグを報告してください-Wextra
。警告の一部のサブセットを明示的に有効にするかどうか-Wextra
は、コード、コーディングスタイル、およびリストを維持することが、で明らかになったすべてを修正するよりも簡単かどうかに大きく依存します-Wextra
。
(両方含ま警告のOPのリスト-Wall
との-Wextra
唯一の次の警告がされている)ではないものを二つのグループによってカバーされ(またはデフォルトでオンになって)。最初のグループは、明示的な警告フラグへの過度の依存が悪い理由を強調しています。これらはどれもClangに実装されていません!GCCとの互換性のためにのみ、コマンドラインで使用できます。
-Wbad-function-cast
-Wdeclaration-after-statement
-Wmissing-format-attribute
-Wmissing-noreturn
-Wnested-externs
-Wnewline-eof
-Wold-style-definition
-Wredundant-decls
-Wsequence-point
-Wstrict-prototypes
-Wswitch-default
元のリストの次の不要な警告のバケットは、そのリストの他の警告と重複しています。
-Wformat-nonliteral
-のサブセット -Wformat=2
-Wshorten-64-to-32
-のサブセット -Wconversion
-Wsign-conversion
-のサブセット -Wconversion
また、より明確に異なる警告の選択もあります。これらは、バグのあるコードやバグのないコードではなく、言語の方言の変形を扱います。を除き-Wwrite-strings
、これらはすべてClangが提供する言語拡張機能に関する警告です。Clangがその使用について警告するかどうかは、拡張機能の普及度に依存します。ClangはGCCの互換性を目的としているため、多くの場合、広く使用されている暗黙の言語拡張機能によってそれを容易にします。-Wwrite-strings
OPでコメントされているように、プログラムのセマンティクスを実際に変更するGCCの互換性フラグです。私はこのフラグを深く後悔していますが、現在のレガシーのためにサポートする必要があります。
-Wfour-char-constants
-Wpointer-arith
-Wwrite-strings
潜在的に興味深い警告を実際に有効にしている残りのオプションは次のとおりです。
-Wcast-align
-Wconversion
-Wfloat-equal
-Wformat=2
-Wimplicit-atomic-properties
-Wmissing-declarations
-Wmissing-prototypes
-Woverlength-strings
-Wshadow
-Wstrict-selector-match
-Wundeclared-selector
-Wunreachable-code
これらが含まれていない、-Wall
または-Wextra
常に明確ではない理由。これらの多くについては、実際にはGCC警告(、など)に基づいている-Wconversion
ため
-Wshadow
、ClangはGCCの動作を模倣しようとします。これらの一部を徐々に、よりきめ細かく有用な警告に分解しています。これらは、トップレベルの警告グループの1つになる可能性が高くなります。それは1回の警告で、選択する、と述べ-Wconversion
ているので、それは可能性が予見可能な将来のために、独自の「トップレベル」カテゴリ残ることを幅広いです。GCCは持っているが、他のいくつかの警告は低い値持っていると高い偽陽性率は、同様の無man's-土地に追いやられます。
これらが大きなバケットの1つに含まれない他の理由には、単純なバグ、非常に重大な誤検知の問題、および開発中の警告が含まれます。識別できるバグのファイリングバグを調べます。最終的にはすべて適切な大きなバケットフラグに移行するか、Clangから削除する必要があります。
これにより、Clangの警告状況が明らかになり、使用または会社の使用のために一連の警告を選択しようとする人々に何らかの洞察が得られることを願っています。