Share via


/external (外部標頭診斷)

編譯 /external 程式選項可讓您指定特定標頭檔之編譯器診斷行為。 「外部」標頭是「Just my code」的自然補充:標頭檔,例如系統檔案或您無法或不想變更的協力廠商程式庫檔案。 由於您不會變更這些檔案,因此您可能會決定從編譯器查看診斷訊息並無用處。 編譯 /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 將值新增至編譯器搜尋 include 檔案的目錄清單。 和 path 之間的 /external:I 空間是選擇性的。 包含空格的目錄必須以雙引號括住。 目錄可能是絕對路徑或相對路徑。

/external:env:var
指定保存外部標頭目錄分號分隔清單的環境變數 var 名稱。 它適用于依賴環境變數的組建系統,例如 INCLUDE ,您用來指定外部 include 檔案的清單。 或者, CAExcludePath 對於不應該由 分析的 /analyze 檔案。 例如,您可以指定 /external:env:INCLUDE 一次將外部標頭目錄中的每個目錄 INCLUDE 設為一次。 這與使用 /external:I 來指定個別目錄相同,但詳細資訊要少得多。 和 /external:env: 之間 var 不應該有空格。

/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 。 檔案 header_file.h 位於 include_dir 包含 program.cpp 檔案的目錄子目錄中:

原始程式檔 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

這個命令列會在 內 header_file.h 隱藏警告,同時保留 內的 program.cpp 警告。

跨內部和外部界限的警告

設定外部標頭的低警告層級可能會隱藏一些可採取動作的警告。 特別是,它可以關閉使用者程式碼中範本具現化時發出的警告。 這些警告可能表示程式碼中只有特定類型的具現化才會發生的問題。 (例如,如果您忘了套用移除 類型特性 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 )

透過對程式庫標頭的這項變更,程式庫的作者可確保此標頭中的全域警告層級為 4,不論 中 /external:Wn 指定的內容為何。 現在會報告所有層級 4 和更新層級的警告。 程式庫作者也可以強制某些警告為錯誤、停用、隱藏或只發出標頭中的一次。 這些 /external 選項不會覆寫該刻意的選擇。

system_header pragma

#pragma system_header 是一個侵入式標記,可讓程式庫寫入器將特定標頭標示為外部。 包含 的 #pragma system_header 檔案會被視為從 pragma 點到檔案結尾的外部檔案,就好像在命令列上指定為外部一樣。 編譯器會在 所指定 /external:Wn 警告層級的 pragma 之後發出任何診斷。 如需詳細資訊,請參閱 system_header pragma

限制

編譯器後端程式碼產生所發出的一些警告不會受到 /external 選項的影響。 這些警告通常從 C47XX 開始,但並非所有 C47XX 警告都是後端警告。 您仍然可以使用 /wd47XX 個別停用這些警告。 程式碼分析警告也不受影響,因為它們沒有警告層級。

在 Visual Studio 開發環境中設定這個編譯器選項

在 Visual Studio 2019 16.10 版和更新版本中:

  1. 開啟專案的 [屬性頁] 對話方塊。 如需詳細資料,請參閱在 Visual Studio 中設定 C ++ 編譯器和組建屬性

  2. 選取 [ 組態屬性 > VC++ 目錄 ] 屬性頁。

  3. 設定 External Include Directory 屬性,以指定每個分號分隔路徑之選項的 /external:I path IDE 對等專案。

  4. 選取 [ 組態屬性 > C/C++ > External Includes ] 屬性頁。

  5. 設定屬性:

    • 將 [包含角括弧的檔案] 設定 為 [外部 ] 設定 為 [是 ] 以設定 /external:anglebrackets 選項。

    • 外部標頭警告層級 可讓您設定 /external:Wn 選項。 如果此值設定為 [繼承專案警告層級 ] 或預設值,則會忽略其他 /external 選項。

    • 將 [外部標頭 中的範本診斷] 設定 為 [ ] 以設定 /external:templates- 選項。

  6. 選擇 [確定 ] 或 [ 套用 ] 以儲存您的變更。

在 Visual Studio 2019 16.10 版之前的 Visual Studio 版本中:

  1. 開啟專案的 [屬性頁] 對話方塊。 如需詳細資料,請參閱在 Visual Studio 中設定 C ++ 編譯器和組建屬性

  2. 選取 [組態屬性]>[C/C++]>[命令列] 屬性頁。

  3. /experimental:external [其他選項 ] 方塊中 輸入選項和其他 /external 編譯器選項。

  4. 選擇 [確定 ] 或 [ 套用 ] 以儲存您的變更。

若要以程式方式設定這個編譯器選項

* 新增 /experimental:external 選項,以在 Visual Studio 2019 16.10 版之前啟用 Visual Studio 版本中的外部標頭選項。

另請參閱

MSVC 編譯器選項
MSVC 編譯器命令列語法