web-dev-qa-db-ja.com

コンパイラの警告を無効にする必要があるのはなぜですか?

この回答 とそれに追加されたコメントは、#pragmaディレクティブを使用していくつかのコンパイラ警告を無効にする方法を示しています。

なぜそんなことをしたいのでしょうか?通常、警告は理由があるので、私は常にそれらが正当な理由であると感じていました。警告を無効にする必要がある「有効なケース」はありますか?今は何も考えられませんが、たぶんそれは私だけです。

26
takrl

警告を無効にした状況は、これまでに1つしかありません。私は警告エラーを考慮するので、通常は警告を出してリリースしません。ただし、顧客でAPIを開発しているときに、移行フェーズで1つのアプリケーションが必要とし、他のアプリケーションが使用すべきではないメソッドをライブラリに含める必要があるという問題に直面しました。

APIのすべてのユーザーに、このメソッドを呼び出すべきではないことを伝えるために私が見つけた最良の方法は、それを古いものとしてマークすることでした。ただし、これは、1つの有効な使用例がコンパイル警告としてマークされたことを意味します。

Eric Lippertが警告についていくつかの投稿を書いており、コンパイラチームが警告についてどのように考えているかについての情報を見つけることができます。

内部タイプの内部フィールド

使用されていないディレクティブを使用しても警告は表示されません

11
Rune FS

いくつかの警告を以下に示します。これらのドキュメントでは、それらを無効にする理由が示されています。

他の例には、古いメソッドを使用したい場合や、ローカルで読み込まれることはなく、代わりにリフレクションを使用するプライベートメンバーがある場合に、減価償却メソッドの使用に関する警告が含まれます。

私の経験では、C#はC++などの他の言語よりも警告を無効にする必要性が少ないです。これは主に、Eric Lippertが彼の blog で述べているように、「コードが壊れている、誤解を招く、または役に立たないとほぼ確実に言える状況のみに警告を予約しようとする」ためです。

10
ICR

Cの例で、私は定期的にバリアントに遭遇します。

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

引数は一部のプラットフォームにのみ関係しますが、関係のないものでは私のコンパイラーが文句を言うでしょう、そして警告をエラーに変換しているのでビルドは妨げられます。

警告をエラーに変換するには、「これではなく、この場合はコンパイラよりもよく知っている」ためのエスケープハッチが必要です。

8
pjc50

多くの不可欠なJavaライブラリは、安全でない型キャストの必要性を排除するために更新されたことはありません。これらの警告を抑制することは、他のより重要な警告に気づき修正するために必要です。

7
kevin cline

組み込み作業を行っていますが、コンパイラーには役に立たないように見えたものの、実際にはハードウェアに実際の影響があったため、警告を無効にしたときのことを覚えています。

他の唯一の時間は、いくつかのデータ構造(バイトの配列-charまたはunsigned charを表す方法など)のさまざまなアイデアを使用してコードベースで作業しているときです。これらの場合、代替策として、コードを何日かかけて一部を変更するか、何百ものキャストを配置することになるため、警告を無効にする場合があります。

5
Michael Kohne

ベストプラクティスを追求するプロジェクトであっても、コンパイラの警告を選択的に無効にする理由はいくつかあります。

  • 異なるコンパイラ(または同じコンパイラの異なるバージョン)
    コンパイラは警告を微妙に異なる方法で処理します。他のコンパイラに影響を与えない偽陽性の警告を出す。この場合、有効なコードを編集して特定のコンパイラにのみ影響を与える偽陽性の警告を静めるのではなく、これらのコンパイラの警告を無効にすることは理にかなっています。
  • 生成されたコード:
    コードの衛生に関連する一部の警告(デッドコード、条件ステートメントの重複ボディ、型の制限を超える比較)は無害であり、コンパイラーがそれらを最適化するため、無視しても問題ありません。
    これらの無害な警告を出さないコードを生成することももちろんオプションですが、その価値よりも問題が多いかもしれません。
  • 外部コードの警告:
    プロジェクトに含まれている、よく知られたqsortまたはmd5チェックサム実装を使用している可能性があります。コードは多くのプロジェクトで使用されており、正常に機能することがわかっていますが、通常は独自のコードを修正するうるさい警告がいくつか表示される場合があります。
    ただし、外部コードの場合は、警告を無効にするだけで面倒が少なくなる可能性があります(その場合はis無害であると想定)。
  • システムヘッダーによる警告:
    たとえばGCC/Clangが-isystemをサポートしている場合でも、システムヘッダーの違いが警告を無視して無視できる場合があります(おそらく、あるシステムでは関数に署名付きの戻り値があり、別のシステムではそうではありません)。 -Wsign-compare警告をトリガーします。
    別のケースとして、システムヘッダーで定義されたマクロが考えられます。マクロを独自のコードにコピーアンドペーストして変更することもできますが、サードパーティのライブラリからのマクロの維持について心配する必要がないことがすべて考慮されました。 。したがって、警告を静めるだけの方が良い(おそらく、マクロがキャストをミスして、-Wsign-conversionを引き起こす)。
  • スタブコード内の未使用の警告:
    未使用のパラメーターについて警告する場合がありますが、スタブ関数のみを含む単一のファイルでライブラリ全体をスタブ化する場合、すべてのスタブ関数の本体で(void)arg1; (void)arg2; (void)arg3; ...を強制することは役に立ちません。
    この場合は-Wunused-parameterを抑制してください。

これらすべての例で、警告を無効にしても、実際のバグが隠されないことに注意してください。例:-Wredundant-decls-Wunused-parameter-Wdouble-promotion、おそらく-Wpedantic ...そして、あなたはあなたが何をしているのか知っている!

3
ideasman42

現在、私が無視している唯一の警告は

 warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

MicrosoftはC++仕様を実装していないため(ドキュメントには実装されていないとも記載されています!)、関数で特定のスローを宣言できます。すべての関数は、throw()またはthrow(...)のいずれかのみをスローできます。つまり、何もまたはすべてをスローできません。

HelpViewer 1.1から:

A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
2
Casey

有効かどうかに関係なく、ビルドサーバーで「警告をエラーとして扱う」ディレクティブをバイパスすることが行われることがあります。

それ以外は何も思いつきません。無効化された警告は通常、「醜いハックス」の兆候です...

2
David Božjak

前回、特定の警告を無効にしたのは、インターンが悪いコードを残していたためです。不規則なデータ表現に代わる明確な変換境界で、私はそれをはるかにうまく機能させています。

その間、コンパイルする必要があり、「警告はエラーです」オプションをオンにする必要があったため、一部の警告を抑制しました。

2
David Thornley