/external(外部ヘッダー 診断)

/externalコンパイラ オプションを使うと、特定のヘッダー ファイルに対するコンパイラの診断動作を指定できます。 "外部" ヘッダーは、"マイ コードのみ" の自然な補完であり、システム ファイルやサードパーティのライブラリ ファイルなど、ユーザーが変更できない、または変更する必要のないヘッダー ファイルです。 これらのファイルを変更することはないため、ユーザーはそれらに関するコンパイラからの診断メッセージを見ても役に立たないと判断することがあります。 /external コンパイラ オプションを使うと、これらの警告を制御できます。

/external コンパイラ オプションは、Visual Studio 2017 バージョン 15.6 以降で使用できます。 Visual Studio 2019 バージョン 16.10 より前のバージョンの Visual Studio では、/external オプションを使うには、/experimental:external コンパイラ オプションも設定する必要があります。

構文

外部ヘッダー オプションを使用します (16.10 以降では不要)。

/experimental:external

外部ヘッダーを指定します。

/external:anglebrackets
/external:env:var
/external:I path

診断動作を指定します。

/external:W0
/external:W1
/external:W2
/external:W3
/external:W4
/external:templates-

引数

/experimental:external
外部ヘッダーのオプションを有効にします。 Visual Studio 2019 バージョン16.10 以降では、このオプションは必要ありません。

/external:anglebrackets
#include <header> によってインクルードされるすべてのヘッダーを処理します。この場合、header ファイルは外部ヘッダーとして山かっこ (< >) で囲まれています。

/external:I path
外部ヘッダーを含むルート ディレクトリを定義します。 path のすべての再帰サブディレクトリは外部と見なされますが、コンパイラがインクルード ファイルを検索するディレクトリのリストには path 値のみが追加されます。 /external:Ipath の間のスペースは省略可能です。 スペースを含むディレクトリは、二重引用符で囲む必要があります。 ディレクトリは、絶対パスでも相対パスでもかまいません。

/external:env:var
外部ヘッダー ディレクトリのセミコロン区切りのリストを保持する環境変数 var の名前を指定します。 これは、外部インクルード ファイルのリストの指定を INCLUDE などの環境変数に依存するビルド システムに便利です。 または、/analyze によって分析してはならないファイルの場合は CAExcludePath。 たとえば、/external:env:INCLUDE を指定して、INCLUDE 内のすべてのディレクトリを一度に外部ヘッダー ディレクトリにすることができます。 これは、/external:I を使って個々のディレクトリを指定するのと同じですが、冗長さがはるかに減ります。 var/external:env: の間にスペースを入れることはできません。

/external:Wn
このオプションは、外部ヘッダーの既定の警告レベルを n (0 から 4 の値) に設定します。 たとえば、/external:W0 と指定すると、外部ヘッダーの警告は実質的にオフになります。 このオプションを指定しないと、コンパイラは他の /external オプションに対してコマンド ラインの警告 D9007 を発行します。 それらのオプションは何の影響もないので、無視されます。

/external:Wn オプションは、インクルードされているヘッダーを #pragma warning ディレクティブにラップするのと同様の効果があります。

#pragma warning (push, 0)
// the global warning level is now 0 here
#include <external_header>
#pragma warning (pop)

/external:templates-
コードでインスタンス化されたテンプレートで発生する外部ヘッダーからの警告を許可します。

解説

既定では、ビルドに対して指定した /Wn 警告レベルは、すべてのファイルに適用されます。 外部ヘッダーを指定するオプションでは、異なる既定の警告レベルを適用できるファイルのセットだけを定義します。 したがって、外部ヘッダーを指定する場合、外部警告レベルを指定してコンパイラの動作を変更するには、/external:Wn も使用します。

警告を有効化、無効化、抑制する既存のメカニズムはすべて、外部と非外部の両方のファイルで変わりなく動作します。 たとえば、warning pragma は、外部ヘッダーに対して設定された既定の警告レベルを引き続きオーバーライドできます。

例: 外部警告レベルを設定する

このサンプル プログラムには、program.cppheader_file.h の 2 つのソース ファイルがあります。 header_file.h ファイルは、program.cpp ファイルが格納されているディレクトリの include_dir サブディレクトリにあります。

ソース ファイル include_dir/header_file.h:

// External header: include_dir/header_file.h

template <typename T>
struct sample_struct
{
    static const T value = -7; // W4: warning C4245: 'initializing':
    // conversion from 'int' to 'unsigned int', signed/unsigned mismatch
};

ソース ファイル program.cpp:

// User code: program.cpp
#include <header_file.h>

int main()
{
    return sample_struct<unsigned int>().value;
}

次のコマンド ラインを使用して、このサンプルをビルドできます。

cl /EHsc /I include_dir /W4 program.cpp

予想どおり、このサンプルでは警告が生成されます。

program.cpp
include_dir\header_file.h(6): warning C4245: 'initializing': conversion from 'int' to 'const T', signed/unsigned mismatch
        with
        [
            T=unsigned int
        ]
program.cpp(6): note: see reference to class template instantiation 'sample_struct<unsigned int>' being compiled

ヘッダー ファイルを外部ファイルとして扱い、警告を非表示にするには、代わりに次のコマンド ラインを使用します*

cl /EHsc /I include_dir /external:anglebrackets /external:W0 /W4 program.cpp

このコマンド ラインを実行すると、program.cpp 内の警告はそのままですが、header_file.h 内の警告は表示されなくなります。

内部と外部の境界を越える警告

外部ヘッダーの警告レベルを低く設定すると、いくつかの対応可能な警告が表示されなくなることがあります。 特に、ユーザー コードでのテンプレートのインスタンス化で生成される警告がオフになることがあります。 これらの警告は、特定の型のインスタンス化でのみ発生するコードでの問題を示している可能性があります。 (たとえば、型特性の削除 const&適用を忘れた場合など)外部ヘッダーで定義されているテンプレート内で警告が消音しないようにするには、このオプションを /external:templates- 使用します。 コンパイラでは、テンプレートが定義されているファイルでの有効な警告レベルと、テンプレートのインスタンス化が発生する箇所での警告レベルの両方が考慮されます。 外部ではないコード内でテンプレートがインスタンス化される場合、外部テンプレートの内部で出力される警告は表示されます。 たとえば、次のコマンド ラインは、サンプル コードのテンプレート ソースからの警告を再度有効にします*

cl /EHsc /I include_dir /external:anglebrackets /external:W0 /external:templates- /W4 program.cpp

テンプレート コードが外部ヘッダー内にある場合でも、出力には C4245 警告が再び表示されます。

警告を有効化、無効化、または抑制する

警告を有効化、無効化、抑制する既存のメカニズムはすべて、外部ヘッダーでも変わりなく動作します。 /external:templates- オプションを使用しているために警告が表示されるときも、インスタンス化の時点で警告を抑制することができます。 たとえば、/external:templates- のために再び表示されるようになったサンプルの警告を明示的に抑制するには、warning pragma ディレクティブを使います。

int main()
{
    #pragma warning( suppress : 4245)
    return sample_struct<unsigned int>().value;
}

ライブラリの作成者は、特定の警告、または特定のレベルのすべての警告を、/external:Wn によって非表示にすべきではないと判断したら、同じメカニズムを使用してそれらの警告を強制的に適用することができます。 たとえば、次のバージョンのヘッダー ファイルでは、強制的に警告 C4245 でエラーを報告させています。

// External header: include_dir/header_file.h

#pragma warning( push, 4 )
#pragma warning( error : 4245 )

template <typename T>
struct sample_struct
{
    static const T value = -7; // W4: warning C4245: 'initializing': conversion from 'int'
                               // to 'unsigned int', signed/unsigned mismatch
};

#pragma warning( pop )

このライブラリ ヘッダーの変更により、ライブラリの作成者は、/external:Wn での指定に関係なく、このヘッダーのグローバル警告レベルを 4 にできます。 これで、レベル 4 以上の警告がすべて報告されます。 また、ライブラリの作成者は、特定の警告を強制的にエラーにする、無効にする、抑制する、またはヘッダーで 1 回だけ出力することもできます。 /external オプションによって、その意図的な選択がオーバーライドされることはありません。

system_header プラグマ

#pragma system_header は、ライブラリの作成者が特定のヘッダーを外部としてマークできる強制的なマーカーです。 #pragma system_header を含むファイルは、その pragma の位置からファイルの最後まで、コマンド ラインで外部として指定されているかのように、外部と見なされます。 コンパイラは、pragma 以降のすべての診断を、/external:Wn によって指定されている警告レベルで出力します。 詳しくは、「system_header pragma」をご覧ください。

制限事項

コンパイラのバックエンド コード生成によって出力される警告の一部は、/external オプションの影響を受けません。 通常、これらの警告は C47XX 以降ですが、すべての C47XX 警告がバックエンドの警告であるとは限りません。 /wd47XX を使用して、これらの警告を個別に無効にすることもできます。 コード分析の警告も、警告レベルがないため影響を受けません。

Visual Studio 開発環境でこのコンパイラ オプションを設定するには

Visual Studio 2019 バージョン 16.10 以降:

  1. プロジェクトの [プロパティ ページ] ダイアログ ボックスを開きます。 詳細については、Visual Studio での C++ コンパイラとビルド プロパティの設定に関する記事を参照してください。

  2. [構成プロパティ]>[VC++ ディレクトリ] プロパティ ページを選択します。

  3. [外部インクルード ディレクトリ] プロパティを設定して、セミコロン区切りの各パスに /external:I path オプションに相当する IDE を指定します。

  4. [構成プロパティ]>[C/C++]>[出力ファイル] プロパティ ページを選択します。

  5. プロパティを設定します。

    • [Treat Files Included with Angle Brackets as External]\(山かっこに含まれるファイルを外部として扱う\)[はい] に設定して、/external:anglebrackets オプションを設定します。

    • [外部ヘッダーの警告レベル] では、/external:Wn オプションを設定できます。 この値が [プロジェクトの警戒レベルの継承] または既定値に設定されている場合、他の /external オプションは無視されます。

    • [外部ヘッダーのテンプレート診断][はい] に設定して、/external:templates- オプションを設定します。

  6. [OK] または [適用] を選択して、変更内容を保存します。

Visual Studio 2019 バージョン 16.10 より前の Visual Studio のバージョン:

  1. プロジェクトの [プロパティ ページ] ダイアログ ボックスを開きます。 詳細については、Visual Studio での C++ コンパイラとビルド プロパティの設定に関する記事を参照してください。

  2. [構成プロパティ]>[C/C++]>[コマンド ライン] プロパティ ページを選択します。

  3. [追加オプション] ボックスに /experimental:external オプションとその他の /external コンパイラ オプションを入力します。

  4. [OK] または [適用] を選択して、変更内容を保存します。

このコンパイラ オプションをコードから設定するには

* Visual Studio 2019 バージョン 16.10 より前のバージョンの Visual Studio で外部ヘッダー オプションを有効にするには、/experimental:external オプションを追加します。

関連項目

MSVC コンパイラ オプション
MSVC コンパイラのコマンド ライン構文