21

プラグマディレクティブの範囲は何ですか?たとえば#pragma warning(disable: 4996)、別のファイルBからインクルードされているヘッダーファイルAで言うと、B内のすべての警告も無効になりますか?または、ファイルAの最後で警告を再度有効にする必要がありますか?

4

3 に答える 3

21

翻訳ユニットの終わりまでです。非公式には、TUはインクルードファイルを含むソースファイルです。

通常のパターンは次のとおりです。

#pragma warning (push) //save
#pragma warning (disable: xxxx)
#pragma warning (disable: yyyy)
...

//code

#pragma warning (pop) //restore prev settings

例えば

//A.h
#pragma once
#pragma warning (disable: 1234)
#include "b.h"

//b.h
#pragma once
//when included after a.h 1234 will be disabled

//c.cpp
#include "a.h" //warnings 1234 from b.h is disabled

//d.cpp
#include "b.h" //warnings 1234 from b.h are not disabled
#include "a.h"
于 2011-02-22T13:24:45.647 に答える
8

プラグマは、使用中のコンパイラとプラットフォームに固有です。したがって、最善の策は、コンパイラのドキュメントを確認することです。

たとえば、IBMコンパイラーの場合:

多くのプラグマディレクティブは、コンパイルユニットのソースコード内の任意の場所で指定できます。その他は、他のディレクティブまたはソースコードステートメントの前に指定する必要があります。各プラグマの個別の説明の「使用法」セクションでは、プラグマの配置に関する制約について説明しています。

一般に、ソースプログラムのコードの前にプラグマディレクティブを指定すると、インクルードされているヘッダーファイルを含むコンパイルユニット全体に適用されます。ソースコードのどこにでも現れることができるディレクティブの場合、それはそれが指定された時点からコンパイルユニットの終わりまで適用されます。

コードの選択したセクションでプラグマディレクティブの補完的なペアを使用することにより、プラグマのアプリケーションの範囲をさらに制限できます。たとえば、次のように#pragmaoptionssourceおよび#pragmaoptionsnosourceディレクティブを使用すると、ソースコードの選択された部分のみがコンパイラリストに含まれるように要求されます。

#pragma options source 

/*  Source code between the source and nosource pragma
    options is included in the compiler listing                */

#pragma options nosource

多くのプラグマには、スタックベースの方法でプラグマ設定を有効または無効にできる「ポップ」または「リセット」サブオプションが用意されています。これらの例は、関連するプラグマの説明に記載されています。

一般に、プラグマは、どのヘッダーから来ても、宣言の直後から翻訳単位の終わりまで有効です。ただし、プログラム全体に影響を与えるプラグマがいくつかあります。たとえば、一部のライブラリへの依存関係を変換ユニットとそのすべての「ユーザー」に追加するMicrosoft固有の「リンク」プラグマ。

于 2011-02-22T13:25:01.947 に答える
1

はい、B内の警告も無効になります。

翻訳ユニットは.cppファイルであり、含まれているすべてのファイルが1つの大きなファイルに展開されます。そのプラグマは、変換ユニットの最後まで、または別の#pragma警告が設定を変更するまで続きます。または、コンパイラが#pragmapushと#pragmapopをサポートしている場合は、次の#pragmapopまで続きます。

'#pragmapush'および'#pragmapop'を使用すると、スコープを作成できます。このようなスコープ内の#pragma警告は、スコープの最後に適用されます。

于 2011-02-22T13:27:08.377 に答える