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


26

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

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


4
誰かがこれをクローズとマークした理由がわかりません。私にとって非常に合理的な質問のようです。+1

@Alastair Pitts:プログラマーへの移行を提案しました。後で自分の間違いに気づきました。
Tugrul ATES

3
警告メッセージには理由があります、はい、しかし、エラーメッセージではない理由もあります。
ソロモンスロー

2
@jameslargeコメントは状況をうまくまとめています。警告は状況があることを伝えるのコンパイラでもっともらしく間違った意味これは、おそらく右。それがあった場合は間違いなく間違っている、それはエラーになります。一部の警告は誤検知である可能性があるため、常に警告を排除するようなコードを記述する方法が必要です。残念ながら、これを行うための最も実用的な方法は、プラグマを使用することです。したがって、名前。
エリックリッパー

無効にするのではなく、非表示にします。問題は、あなたがそれをそのまま見ることができないというだけで、まだそこにあります
Sisir

回答:


11

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

APIのすべてのユーザーに、このメソッドを呼び出してはならないことを伝える最善の方法は、このメソッドを廃止とマークすることでした。ただし、これは、1つの有効なユースケースがコンパイル警告としてマークされたことを意味します。

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

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

未使用のusingディレクティブには警告のマークが付いていません


10

以下に、ドキュメントで警告を無効にする理由を説明する警告をいくつか示します。

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

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


3
いいね 最初のものは非常に明確であると思います、なぜならそれは非常に具体的なケース正当性を提供するからです(たとえば、3番目は私のチームでレビューを決して渡さないコードの断片を示しています)。 この質問では、廃止/廃止された警告について説明します。基本的に、これらはレガシーコードでも引き続き必要ですが、新しいコードを使用しないようにする必要があります。レガシコードでは、警告を抑制する必要があります。
グレッグジャクソン

Excelで多くのマクロプログラミングを行ったので、自動保存、自動終了、通知などのさまざまな理由で警告を無効にする必要がありました。もちろん、これらの警告については説明しないかもしれません...
Dave Mess

@ICR Javaでコンパイラの警告を無効にしたことをまったく覚えていません。非推奨のメソッドを使用しないようにするだけです。
マフムードホッサム

@Mahmoud私は非常に頻繁に、ジェネリックでリモートで複雑なことをするとき、「チェックされていない」警告を抑制する必要があることに気付きます。しかし、ばかげた警告の前でJavaをC ++にまとめるのはおそらく不公平です-私の答えを編集しました。
ICR

@ICR Javaはジェネリックの使用を強制してコレクションのタイプセーフを提供しますが、これを制約と見なしている人もいますが、機能と考えています。コードを書くのは少し苦痛になりますが、命を救います、そしてC ++コンパイラ出力STLまたはテンプレートを使用する場合は、少し怖いです。
マフムードホッサム

8

私は定期的にのバリアントに遭遇するCの例:

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

引数は一部のプラットフォームにのみ関係しますが、関係のないプラットフォームではコンパイラーが文句を言い、エラーに変換された警告があるため、ビルドできません。

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


6

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


5

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

それ以外の場合は、データ構造の異なるアイデア(バイト配列-charまたはunsigned charの表現方法など)を使用してコードベースで作業しているときだけです。これらのケースでは、コードを調べて1つの部分を変更するか、何百ものキャストを入力するのに何日も費やすことになるため、警告を無効にすることができます。


3

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

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

:すべてのこれらの例では、その前提と警告を無効にするなど、実際のバグを非表示にするつもりはないことに注意してください-Wredundant-decls-Wunused-parameter-Wdouble-promotion多分、-Wpedantic...あなたは何をやっている知っています!


2

有効かどうかにかかわらず、ビルドサーバー上の "警告をエラーとして扱う"ディレクティブをバイパスすることがあります。

それ以外は考えられない。無効化された警告は、通常「 "いハックス」の兆候です...


2

前回特定の警告を無効にしたのは、インターンが悪いコードを残していたためです。偶然のデータ表現を明確な変換境界に置き換えることで、私はそれをより良く機能させました。

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


2

現在、私が今まで無視した唯一の警告は

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

マイクロソフトは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. 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.