最近、プロジェクトで-Wall
を有効にしました。 GCC diagnostic
を使用して昇格された警告からの出力を管理できるため、GCCが4.7以上(またはClang)のときに有効になります。それらをソースコードから管理し、notコマンドライン引数で管理します。 (コマンドラインを汚染したり、ライブラリのユーザーに必要なものを再発見したりすることは望んでいません)。
GCC 4.8および5.1では、-Wunused-variable
、-Wunused-value
、-Wunused-function
および-Wunknown-pragmas
のGCC診断ブロックで無効にされた警告をキャッチしています。どちらのGCCも-fopenmp
を受け入れ、それに応答して_OPENMP
を定義しているため、-Wunknown-pragmas
に応答して#prgam omp ...
が表示されることはないと確信しています。 is無効、ただしis not不明)。
g++ -DNDEBUG -g2 -O3 -Wall -march=native -pipe -c nbtheory.cpp
nbtheory.cpp:655:0: warning: ignoring #pragma omp parallel [-Wunknown-pragmas]
#pragma omp parallel
^
nbtheory.cpp:656:0: warning: ignoring #pragma omp sections [-Wunknown-pragmas]
#pragma omp sections
^
...
この特定のケースでは、 file nbtheroy.cpp
は、その警告の管理に役立つ次のガードを備えています(関連する部分のみが示されていますが、 GitHubリンクからすべてを表示できます) ):
// Defines GCC_DIAGNOSTIC_AWARE if GCC 4.7 or above.
#include <misc.h>
...
#if GCC_DIAGNOSTIC_AWARE
# pragma GCC diagnostic ignored "-Wunknown-pragmas"
#endif
...
Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq,
const Integer &p, const Integer &q, const Integer &u)
{
Integer p2, q2;
#pragma omp parallel
#pragma omp sections
{
#pragma omp section
p2 = ModularExponentiation((a % p), dp, p);
#pragma omp section
q2 = ModularExponentiation((a % q), dq, q);
}
return CRT(p2, p, q2, q, u);
}
...
ファイルは*.cpp
(事実上the翻訳単位)であるため、次のようになりますしないでください最初に#pragma GCC diagnostic Push
を実行し、最後に#pragma GCC diagnostic pop
を実行します。 (ただし、インクルードされるヘッダーファイルについてはこれを行います)。 (私たちはそれを試みましたが、助けにはなりませんでした)。
そして、これがGCC_DIAGNOSTIC_AWARE
です(from misc.h
):
// Used to suppress some warnings in some header and implementation files.
// Some platforms, like CentOS and OpenBSD, use old compilers that don't understand -Wno-unknown-pragma.
#define GCC_DIAGNOSTIC_AWARE ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__))
ブロックに#error
を追加するとエラーが発生するため、ガードが機能していることがわかります。また、警備員をコメントアウトして#pragma GCC diagnostic ignored "-Wunknown-pragmas"
を呼び出すことは役に立ちません。最後に、それはClangで正常に動作します。
-Wunused-variable
、-Wunused-value
、-Wunused-function
などの他の警告でも発生しています。私本当に重複の可能性があることを示唆しているように、コマンドラインを汚染したくありません。
GCC pragma diagnostic
メカニズムを使用して、GCCで-Wall
を使用しているときに警告が表示されないようにするにはどうすればよいですか?
関連、それを再現したい場合(そのGNUmakefileベースで、構成やautotoolsは必要ありません):
git clone https://github.com/weidai11/cryptopp.git cryptopp-warn
cd cryptopp-warn
make
[〜#〜] edit [〜#〜]:Clang以外の-Wall
を無効にするパッチをチェックインしました。古い動作を再現したい場合は、次のようにします。
git clone https://github.com/weidai11/cryptopp.git cryptopp-warn
cd cryptopp-warn
export CXXFLAGS="-g2 -O3 -DNDEBUG -Wall"
make
これは少なくともgcc
のバグのようです。次のコード:
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wuninitialized"
int fn(void) {
#pragma xyzzy
int x;
return x;
}
int main (void) {
return fn();
}
初期化されていないx
値を無視しても問題はありませんが、プラグマについて不満があります(uninitialized
プラグマがないと、予想どおりx
の警告が生成されます)。
コマンドラインオプションを-Wall -Wno-unknown-pragmas
に変更すると、問題なく無視されます。翻訳単位全体に適用したいので、特定のケースでは問題ありませんが、#pragma
メソッドから取得できる細かい制御はできません(機能した場合)。
GCCのバグレポートを上げに行きましたが、すでに存在していることがわかりました( #53431 )。
この特定のバグは-Wundef
に関係していますが、コメントの1つのスニペットは、プリプロセッサに影響するすべてのバリアントに適用されることを示しています(強調のために少し変更されています)。
C++パーサーlexes(andpreprocesses)は、プラグマを処理する前に実行しますが、Cパーサーはプラグマを認識したとおりに処理します。
cp/parser.c:631
のこれらのプラグマalsoを何らかの方法で解析する必要があります。おそらく、cp_parser_initial_pragma
の場合と同様のことを実行できますが、ループ内でプラグマ診断のみを処理できます。確かに、それを正しく行うには、試行錯誤が必要です。試してみたいと思って助けが必要な場合は、ここまたはメーリングリストで質問してください。
これが、-Wuninitialized
で同じ問題が発生しない理由を説明しています。これは、前処理の最後にプラグマがアクティブ化された後、コンパイルプロセスの後の段階で検出されるためです。
したがって、よりタイムリーに修正された状態で(3年以上前に発生した)修正を確認したい場合は、GCCのBugzillaサイトを手間をかけて公開してみることをお勧めします。