web-dev-qa-db-ja.com

#pragma warningプッシュ/ポップを使用して、一時的に警告レベルを変更していますか?

時々、警告をまったく出さないC++コードを書くのは困難です。ただし、警告を有効にすることをお勧めします。そのため、特定の構成要素に関する警告を無効にし、他のすべてのコードで警告を有効にする必要があることがよくあります。

これまでに2つの方法を見てきました。

最初の方法は、#pragma warning( Push )および#pragma warning( pop )を使用することです。

_ #pragma warning( Push )
 #pragma warning( disable: ThatWarning )
 //code with ThatWarning here
 #pragma warning( pop )
_

2番目は#pragma warning( default )を使用することです:

_ #pragma warning( disable: ThatWarning )
 //code with ThatWarning here
 #pragma warning( default: ThatWarning )
_

2番目のバリアントで見られる問題は、元の警告レベルを破棄することです。その前に警告がオフになっているか、警告レベルが変更されている可能性があります。 defaultを使用すると、これらの変更は破棄されます。

最初のアプローチはきれいに見えます。それに問題はありますか?同じことを達成するより良い方法はありますか?

66
sharptooth

最初の方法はそれを行う最良の方法、IMOです。私はそれで問題がないことを知っています。

#pragmaはコンパイラ固有であるため、すべてのコンパイラで動作するとは思わないでください:)

34
Goz

これは、複数のコンパイラー(および異なるバージョンのコンパイラー)で機能します。

ヘッダー「プッシュ」

#if defined(__clang__)
# pragma clang diagnostic Push
#endif

#if defined(_MSC_VER)
# pragma warning(Push)
#endif

#if defined(YOUR_FAVORITE_COMPILER)
# pragma your compiler Push warning
#endif

ヘッダー「ポップ」

#if defined(__clang__)
# pragma clang diagnostic pop
#endif

#if defined(_MSC_VER)
# pragma warning(pop)
#endif

いくつかの警告

#if defined(__clang__)
# pragma clang diagnostic ignored "-Wunused-parameter"
# pragma clang diagnostic ignored "-Wunused-variable"
#  if __has_warning("-Wnew-special-warning")
#   pragma clang diagnostic ignored "-Wnew-special-warning"
#  endif
#endif

#if defined(_MSC_VER)
# pragma warning(disable: 4100) // unreferenced formal parameter
# if _MSC_VER > _MSC_SOME_VERSION
#  pragma warning(disable: xxxx) // disable one more for special version
# endif
#endif

使用法

// This code reports warnings
// ...
#include <ignore_compiler_warning/Push>
#include <ignore_compiler_warning/warning_type_1>
#include <ignore_compiler_warning/warning_type_2>
#include <ignore_compiler_warning/warning_type_3>
// This code ignores warnings type_{1,2,3}
// ...
#include <ignore_compiler_warning/pop>
// Back to reporting warnings
// ...

さらに、ガードは、プッシュ/ポップ/警告を無効にするプラグマが二重にないことを確認できます。

更新

40
user2288008

Sharptoothには遅すぎるが、そこにいるすべてのグーグルには遅すぎる:

#pragma warning ( suppress: ThatWarning )
// one single line with ThatWarning

(一般的には VS 2008以降 ですが、 VS 2005の場合 コードアナライザーの警告のみ):

#pragma warning ( Push )
#pragma warning ( disable: ThatWarning )
// one single line with ThatWarning
#pragma warning ( pop )
37
m3tikn0b

正しいアプローチ(少しいですが)

#ifdef _MSC_VER
 #pragma warning( Push )
 #pragma warning( once: ThatWarning )
#endif
 //code with ThatWarning here
#ifdef _MSC_VER
 #pragma warning( pop )
#endif
13
ronag

プロジェクトまたはファイルオプションで特定の警告を無効にできます。この設定は、関連するスコープの#pragmasごとに「デフォルト」として適用されます。 VS2005の警告の中には、/W4を使用する場合、出力がかなりクリーンアップされるほど役に立たない/煩わしいものがあります。

これは、[構成プロパティ]-> [C/C++]-> [詳細]の[プロパティ]にあります。

3
Steve Townsend

最初のバリアントには問題ありません。より良い方法は、次を使用することです。

 #pragma warning( Push )
 #pragma warning( once: ThatWarning )
 //code with ThatWarning here
 #pragma warning( pop )

これにより、コードにまだ警告があることがわかりますが、警告メッセージはそれほど面倒ではありません。しかし、それは好みの問題です。