/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.cpp
header_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 版和更新版本中:
開啟專案的 [屬性頁] 對話方塊。 如需詳細資料,請參閱在 Visual Studio 中設定 C ++ 編譯器和組建屬性。
選取 [組態屬性>VC++ 目錄] 屬性頁。
設定 External Include Directory 屬性,以指定每個分號分隔路徑之選項的
/external:I path
IDE 對等專案。選取 [組態屬性>C/C++>External Includes 屬性頁。
設定屬性:
將 [包含角括弧的檔案] 設定 為 [外部 ] 設定 為 [是 ] 以設定
/external:anglebrackets
選項。外部標頭警告層級 可讓您設定
/external:Wn
選項。 如果此值設定為 [繼承專案警告層級 ] 或預設值,則會忽略其他/external
選項。將 [外部標頭中的範本診斷] 設定為 [是] 以設定
/external:templates-
選項。
選擇 [確定] 或 [套用] 以儲存變更。
在 Visual Studio 2019 16.10 版之前的 Visual Studio 版本中:
開啟專案的 [屬性頁] 對話方塊。 如需詳細資料,請參閱在 Visual Studio 中設定 C ++ 編譯器和組建屬性。
選取 [組態屬性]>[C/C++]>[命令列] 屬性頁。
在
/experimental:external
[其他選項] 方塊中輸入選項和其他/external
編譯程序選項。選擇 [確定] 或 [套用] 以儲存變更。
若要以程式方式設定這個編譯器選項
- 請參閱 AdditionalOptions。
* 新增 /experimental:external
選項,以在 Visual Studio 2019 16.10 版之前啟用 Visual Studio 版本中的外部標頭選項。