翻訳ユニットの一部に対してのみGCC警告を選択的に無効にしますか?


85

このMSVCプリプロセッサコードに相当する最も近いGCCは何ですか?

#pragma warning( push )                    // Save the current warning state.
#pragma warning( disable : 4723 )          // C4723: potential divide by 0
// Code which would generate warning 4723.
#pragma warning( pop )                     // Restore warnings to previous state.

一般的に含まれているヘッダーに、特定の警告を生成したくないコードがあります。ただし、これらのヘッダーを含むファイルは、引き続きその警告を生成する必要があります(プロジェクトでその警告が有効になっている場合)。


ヘッダーが/ usr / includeにインストールされている場合、またはgccがデフォルトで警告を生成しない場合。
Spudd86 2010年

回答:


95

これは、バージョン4.6以降のGCC、またはトランクの2010年6月頃に可能です。

次に例を示します。

#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wuninitialized"
    foo(a);         /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(b);         /* no diagnostic for this one */
#pragma GCC diagnostic pop
    foo(c);         /* error is given for this one */
#pragma GCC diagnostic pop
    foo(d);         /* depends on command line options */

8
プッシュおよびポップ機能はgcc4.6gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html)で追加されました。
Dave Johansen 2011

2回ポップする場合は、おそらく2回プッシュすることをお勧めします。
ダン

2
@ダン:マニュアルを読んでコメントしてください。例の起源に注意してください。
マットジョイナー2014年

4.4.7などの古いバージョンの参考までに、引き続き使用できます#pragma GCC diagnostic [error|warning|ignored]が、pop実装/サポートされていません。
Trevor Boyd Smith

36

最も近いのは、GCC診断プラグマです#pragma GCC diagnostic [warning|error|ignored] "-Wwhatever"。それはあなたが望むものにあまり近くありません、そして詳細と警告のためにリンクを見てください。


1
この機能を追加しない理由がどこにあるのか知っていますか?(見つかりませんでした。)警告push-disable-popが便利だと思います。

1
gccに「機能を追加しない」というのは、作業パッチを提出する人がいないほどの論理的根拠がある傾向があるとは、私は本当に想像していません。
カオス

14
gccでこの種のきめ細かい警告制御の作業をしたり、コードを提出したりする人がいないわけではありません-すでにこれを行っているシリコンバレーの大手企業と、誰かにお金を払って喜んでいる企業を知っていますそれを実行し、コードをストリームに取り込みます。むしろ、(gdbメンテナの1人として)このようなものに接続されている人との話し合いによると、gccメンテナは「警告がある場合、それはバグであり、修正する必要がある」という哲学を持っています。だから(imo)それは宗教的な議論であり、彼らは勝つようにコードを制御します。
ボブマーフィー

ボブのコメントに加えて、GCC開発者は#pragmaディレクティブを嫌った歴史があるので、GCC固有のものはおそらくとして実装される可能性が高くなります__attribute__((foo))
トム

10
新しいgccが(> = 4.4)を持っている#pragma GCC push_optionsあなただけの診断よりも...とについてマックできるよう gcc.gnu.org/onlinedocs/gcc/...
Spudd86

33

私は似たようなことをしました。サードパーティのコードについては、警告をまったく表示したくありませんでした。したがって、指定するのではなく-I/path/to/libfoo/include、を使用しました-isystem /path/to/libfoo/include。これにより、コンパイラは警告の目的でこれらのヘッダーファイルを「システムヘッダー」として扱い-Wsystem-headersます。有効にしない限り、ほとんど安全です。私はまだいくつかの警告がそこから漏れているのを見てきましたが、それはほとんどのがらくたを減らします。

これ、問題のあるコードをinclude-directoryで分離できる場合にのみ役立つことに注意してください。それがあなた自身のプロジェクトのサブセットであるか、他のコードと混ざっているなら、あなたは運が悪いです。


1
素晴らしいヒント。LLVMを使用している場合は、「AppleLLVMコンパイラ-言語」セクションの「その他のCフラグ」の下に-isystemフラグを追加します。
Nestor

@トム共有してくれてありがとう。ソリューションをどこで使用すればよいかわかりません。もう少し言えますか?
Lorenzo B

1

これは、マットジョイナーの答えを拡張したものです。

コード全体にプラグマを生成したくない場合は、_Pragma演算子を使用できます。

#ifdef __GNUC__
#  define DIAGNOSTIC_ERROR(w) _Pragma("GCC diagnostic error \"" w "\"")
#  define DIAGNOSTIC_IGNORE(w) _Pragma("GCC diagnostic ignore \"" w "\"")
#  define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
#  define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#endif
// (...)

DIAGNOSTIC_ERROR("-Wuninitialized")
foo(a); // Error

DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE("-Wuninitialized")
foo(a); // No error

DIAGNOSTIC_POP
foo(a); // Error
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.