預先定義巨集
Microsoft C/C++ 編譯程式 (MSVC) 會根據語言 (C 或 C++)、編譯目標及所選編譯程式選項,預先定義特定的預處理器巨集。
MSVC 支援 ANSI/ISO C99、C11 和 C17 標準所需的預先預處理器巨集,以及 ISO C++14、C++17 和 C++20 標準。 實作也支援更多Microsoft特定預處理器巨集。
某些巨集只會針對特定建置環境或編譯程式選項定義。 除了註明的位置之外,巨集會定義在整個轉譯單位中,如同它們已指定為 /D
編譯程式選項自變數一樣。 定義時,預處理器會在編譯之前展開巨集的指定值。 預先定義的巨集不會接受任何自變數,而且無法重新定義。
標準預先定義的標識碼
編譯程式支援 ISO C99 和 ISO C++11 所指定的這個預先定義標識碼。
__func__
封入函式的非限定和未限定名稱,做為 的函式本機 靜態 const 陣列char
。void example() { printf("%s\n", __func__); } // prints "example"
標準預先定義的巨集
編譯程式支援 ISO C99、C11、C17 和 ISO C++17 標準所指定的這些預先定義巨集。
__cplusplus
當轉譯單位編譯為C++時,定義為整數常值。 否則為未定義。__DATE__
目前原始程式檔的編譯日期。 日期是 Mmm dd yyyy 格式的常數長度字串常值。 月份名稱 Mmm 與 C 執行時間連結庫 (CRT) asctime 函式所產生的縮寫月份名稱相同。 如果值小於 10,則 date dd 的第一個字元是空格。 這個巨集一律會定義。__FILE__
目前原始程式檔的名稱。__FILE__
展開為字元字串常值。 若要確保檔案的完整路徑已顯示,請使用/FC
[診斷] 中原始碼檔案的完整路徑。 這個巨集一律會定義。__LINE__
定義為目前原始程序檔中的整數行號。 您可以使用 指示詞來變更#line
這個巨集的值。 值的__LINE__
整數型別可能會根據內容而有所不同。 這個巨集一律會定義。__STDC__
在編譯為 C 時定義為 1,如果指定編譯程式選項,則/Za
為 1。 從 Visual Studio 2022 17.2 版開始,當編譯為 C 時,如果/std:c11
指定 或/std:c17
編譯程式選項,則會將其定義為 1。 否則為未定義。__STDC_HOSTED__
如果實作是 託管實作,則定義為1,其中一個支援整個必要標準連結庫。 否則,定義為 0。__STDC_NO_ATOMICS__
如果實作不支援選擇性標準不可部分完成,則定義為1。 MSVC 實作會在編譯為 C 時將其定義為 1,並指定其中一個/std
C11 或 C17 選項。__STDC_NO_COMPLEX__
如果實作不支援選擇性標準複數,則定義為1。 MSVC 實作會在編譯為 C 時將其定義為 1,並指定其中一個/std
C11 或 C17 選項。__STDC_NO_THREADS__
如果實作不支援選擇性標準線程,則定義為1。 MSVC 實作會在編譯為 C 時將其定義為 1,並指定其中一個/std
C11 或 C17 選項。__STDC_NO_VLA__
如果實作不支持標準可變長度陣列,則定義為1。 MSVC 實作會在編譯為 C 時將其定義為 1,並指定其中一個/std
C11 或 C17 選項。__STDC_VERSION__
當編譯為 C,並指定其中/std
一個 C11 或 C17 選項時定義。 它會針對 展開至201112L
/std:c11
,而201710L
針對/std:c17
。__STDCPP_DEFAULT_NEW_ALIGNMENT__
指定或更新版本時/std:c17
,這個巨集會展開為size_t
常值,該常值具有由呼叫 alignment-unawareoperator new
所保證的對齊值。 較大的對齊方式會傳遞至對齊感知多載,例如operator new(std::size_t, std::align_val_t)
。 如需詳細資訊,請參閱/Zc:alignedNew
(C++17 過度對齊的配置)。__STDCPP_THREADS__
只有在程式可以有多個線程執行,並編譯為 C++ 時,才會定義為 1。 否則為未定義。__TIME__
前置處理之翻譯單位的翻譯時間。 時間是 hh:mm:ss 格式的字元字串常值,與 CRT asctime 函式傳回的時間相同。 這個巨集一律會定義。
Microsoft特定預先定義的巨集
MSVC 支援其他預先定義的巨集:
__ARM_ARCH
定義為代表ARM架構版本的整數常值。 此值定義為Armv8-A架構的8。 針對 8.1 和更新版本,會使用 ARM C 語言延伸模組所定義的公式 X * 100 + Y 來調整次要版本的值,例如 X.Y。 例如,針對 Armv8.1,__ARM_ARCH
是 8 * 100 + 1 或 801。 若要設定 ARM 架構版本,請參閱/arch (ARM64)
。 此巨集是在Visual Studio 2022 17.10版中引進的。__ATOM__
當編譯程式選項設定且編譯程式目標為 x86 或 x64 時/favor:ATOM
,定義為 1。 否則為未定義。__AVX__
當 設定、/arch:AVX2
/arch:AVX512
或/arch:AVX10.1
編譯程式選項且編譯程式目標為 x86 或 x64 時/arch:AVX
,定義為 1。 否則為未定義。__AVX2__
當設定 或/arch:AVX512
/arch:AVX10.1
編譯程式選項且編譯程式目標為 x86 或 x64 時/arch:AVX2
,定義為 1。 否則為未定義。__AVX512BW__
當 或/arch:AVX10.1
編譯程式選項設定且編譯程式目標為 x86 或 x64 時/arch:AVX512
,定義為 1。 否則為未定義。__AVX512CD__
當 或/arch:AVX10.1
編譯程式選項設定且編譯程式目標為 x86 或 x64 時/arch:AVX512
,定義為 1。 否則為未定義。__AVX512DQ__
當 或/arch:AVX10.1
編譯程式選項設定且編譯程式目標為 x86 或 x64 時/arch:AVX512
,定義為 1。 否則為未定義。__AVX512F__
當 或/arch:AVX10.1
編譯程式選項設定且編譯程式目標為 x86 或 x64 時/arch:AVX512
,定義為 1。 否則為未定義。__AVX512VL__
當 或/arch:AVX10.1
編譯程式選項設定且編譯程式目標為 x86 或 x64 時/arch:AVX512
,定義為 1。 否則為未定義。__AVX10_VER__
定義為整數,表示設定編譯程式選項且編譯程式目標為 x86 或 x64 時的/arch:AVX10.1
AVX10 版本。 否則為未定義。_CHAR_UNSIGNED
如果預設char
類型為不帶正負號,則定義為1。 設定 [預設字元類型未帶正負號] 編譯程序選項時/J
,就會定義這個值。 否則為未定義。__CLR_VER
定義為整數常值,表示用來編譯應用程式的 Common Language Runtime (CLR) 版本。 值會以 格式Mmmbbbbb
編碼,其中M
是運行時間的主要版本,mm
是運行時間的次要版本,而bbbbb
是組建編號。__CLR_VER
如果已設定編譯程式選項,則會/clr
定義 。 否則為未定義。// clr_ver.cpp // compile with: /clr using namespace System; int main() { Console::WriteLine(__CLR_VER); }
_CONTROL_FLOW_GUARD
當設定 [啟用控制流程防護] 編譯程序選項時/guard:cf
,定義為 1。 否則為未定義。__COUNTER__
展開至從 0 開始的整數常值。 每次在原始程式檔或來源檔案的內含標頭中使用該值時,值就會遞增 1。__COUNTER__
當您使用先行編譯標頭時,會記住其狀態。 這個巨集一律會定義。這個範例會使用
__COUNTER__
將唯一標識符指派給相同型別的三個不同物件。 建exampleClass
構函式會採用整數作為參數。 在main
中,應用程式會宣告類型exampleClass
為 的三個物件,並使用__COUNTER__
做為唯一標識符參數:// macro__COUNTER__.cpp // Demonstration of __COUNTER__, assigns unique identifiers to // different objects of the same type. // Compile by using: cl /EHsc /W4 macro__COUNTER__.cpp #include <stdio.h> class exampleClass { int m_nID; public: // initialize object with a read-only unique ID exampleClass(int nID) : m_nID(nID) {} int GetID(void) { return m_nID; } }; int main() { // __COUNTER__ is initially defined as 0 exampleClass e1(__COUNTER__); // On the second reference, __COUNTER__ is now defined as 1 exampleClass e2(__COUNTER__); // __COUNTER__ is now defined as 2 exampleClass e3(__COUNTER__); printf("e1 ID: %i\n", e1.GetID()); printf("e2 ID: %i\n", e2.GetID()); printf("e3 ID: %i\n", e3.GetID()); // Output // ------------------------------ // e1 ID: 0 // e2 ID: 1 // e3 ID: 2 return 0; }
__cplusplus_cli
當編譯為 C++ 並/clr
設定編譯程式選項時,定義為整數常值200406。 否則為未定義。 定義時,__cplusplus_cli
會在轉譯單位中生效。// cplusplus_cli.cpp // compile by using /clr #include "stdio.h" int main() { #ifdef __cplusplus_cli printf("%d\n", __cplusplus_cli); #else printf("not defined\n"); #endif }
__cplusplus_winrt
當編譯為 C++ 且/ZW
已設定 [Windows 執行階段 編譯] 編譯程式選項時,定義為整數常值201009。 否則為未定義。_CPPRTTI
如果/GR
已設定 [啟用運行時間類型資訊] 編譯程式選項, 則定義為 1。 否則為未定義。_CPPUNWIND
如果已設定一或多個/GX
[啟用例外狀況處理]、/clr
[Common Language Runtime 編譯] 或/EH
[例外狀況處理模型] 編譯程序選項,則定義為 1。 否則為未定義。__FUNCDNAME__
定義為字串常值,其中包含 封入函式的裝飾名稱 。 巨集只會在函式內定義。 如果您使用/EP
或/P
編譯程序選項,則__FUNCDNAME__
不會展開巨集。這個範例會
__FUNCDNAME__
使用、__FUNCSIG__
和__FUNCTION__
巨集來顯示函式資訊。// Demonstrates functionality of __FUNCTION__, __FUNCDNAME__, and __FUNCSIG__ macros void exampleFunction() { printf("Function name: %s\n", __FUNCTION__); printf("Decorated function name: %s\n", __FUNCDNAME__); printf("Function signature: %s\n", __FUNCSIG__); // Sample Output // ------------------------------------------------- // Function name: exampleFunction // Decorated function name: ?exampleFunction@@YAXXZ // Function signature: void __cdecl exampleFunction(void) }
__FUNCSIG__
定義為包含封入函式簽章的字串常值。 巨集只會在函式內定義。 如果您使用/EP
或/P
編譯程序選項,則__FUNCSIG__
不會展開巨集。 針對 64 位目標編譯時,呼叫慣例預設為__cdecl
。 如需使用方式的範例,請參閱__FUNCDNAME__
巨集。__FUNCTION__
定義為包含封入函式未編碼名稱的字串常值。 巨集只會在函式內定義。 如果您使用/EP
或/P
編譯程序選項,則__FUNCTION__
不會展開巨集。 如需使用方式的範例,請參閱__FUNCDNAME__
巨集。_INTEGRAL_MAX_BITS
定義為整數常值 64,非向量整數型別的大小上限(以位為單位)。 這個巨集一律會定義。// integral_max_bits.cpp #include <stdio.h> int main() { printf("%d\n", _INTEGRAL_MAX_BITS); }
__INTELLISENSE__
在 IntelliSense 編譯程式傳入 Visual Studio IDE 期間定義為 1。 否則為未定義。 您可以使用這個巨集來保護 IntelliSense 編譯程式無法理解的程式代碼,或使用它來切換組建和 IntelliSense 編譯程式之間的程式代碼。 如需詳細資訊,請參閱 IntelliSense 緩慢的疑難解答秘訣。_ISO_VOLATILE
如果已設定編譯程式選項,/volatile:iso
則定義為 1。 否則為未定義。_KERNEL_MODE
如果/kernel
已設定 [建立核心模式二進位檔] 編譯程序選項, 則定義為 1。 否則為未定義。_M_AMD64
定義為以 x64 處理器或ARM64EC為目標之編譯的整數常值 100。 否則為未定義。_M_ARM
定義為以ARM處理器為目標之編譯的整數常值7。 未定義 ARM64、ARM64EC和其他目標。_M_ARM_ARMV7VE
當編譯程式選項設定為以ARM處理器為目標的編譯時/arch:ARMv7VE
,定義為1。 否則為未定義。_M_ARM_FP
定義為整數常值,指出為 ARM 處理器目標設定的/arch
編譯程式選項。 否則為未定義。如果未
/arch
指定 ARM 選項,則為範圍 30-39 中的值,表示已設定 ARM 的預設架構(VFPv3
)。如果
/arch:VFPv4
已設定,則為範圍 40-49 中的值。如需詳細資訊,請參閱
/arch
(ARM)。
_M_ARM64
定義為以ARM64為目標之編譯的1。 否則為未定義。_M_ARM64EC
定義為 1,用於以ARM64EC為目標的編譯。 否則為未定義。_M_CEE
如果已設定任何/clr
[Common Language Runtime 編譯] 編譯程序選項, 則定義為 001。 否則為未定義。_M_CEE_PURE
從 Visual Studio 2015 開始淘汰。 如果已設定編譯程式選項,/clr:pure
則定義為 001。 否則為未定義。_M_CEE_SAFE
從 Visual Studio 2015 開始淘汰。 如果已設定編譯程式選項,/clr:safe
則定義為 001。 否則為未定義。_M_FP_CONTRACT
從 Visual Studio 2022 開始提供。 如果 已設定 或/fp:fast
編譯程式選項,/fp:contract
則定義為 1。 否則為未定義。_M_FP_EXCEPT
如果 已設定 或/fp:strict
編譯程式選項,/fp:except
則定義為 1。 否則為未定義。_M_FP_FAST
如果已設定編譯程式選項,/fp:fast
則定義為 1。 否則為未定義。_M_FP_PRECISE
如果已設定編譯程式選項,/fp:precise
則定義為 1。 否則為未定義。_M_FP_STRICT
如果已設定編譯程式選項,/fp:strict
則定義為 1。 否則為未定義。_M_IX86
定義為以 x86 處理器為目標之編譯的整數常值 600。 此巨集未針對 x64 或 ARM 編譯目標定義。_M_IX86_FP
定義為整數常值,指出/arch
已設定的編譯程式選項或預設值。 當編譯目標為 x86 處理器時,一律會定義這個巨集。 否則為未定義。 定義時,值為:如果已設定編譯程式選項,則為
/arch:IA32
0。如果已設定編譯程式選項,則為
/arch:SSE
1。如果已設定 、
/arch:AVX
、/arch:AVX2
或/arch:AVX10.1
編譯程序選項,/arch:AVX512
則為/arch:SSE2
2。 如果未/arch
指定編譯程式選項,則此值為預設值。 指定 時/arch:AVX
,也會定義巨集__AVX__
。 指定 時/arch:AVX2
,__AVX__
也會定義 和__AVX2__
。 當 指定時/arch:AVX512
,__AVX__
也會定義 、、__AVX512DQ__
__AVX2__
__AVX512BW__
__AVX512CD__
、__AVX512F__
和 。__AVX512VL__
當 指定時/arch:AVX10.1
,__AVX__
也會定義 、、__AVX512DQ__
__AVX512CD__
__AVX2__
__AVX512BW__
、__AVX512F__
__AVX512VL__
和 。__AVX10_VER__
如需詳細資訊,請參閱
/arch
(x86) 。
_M_X64
定義為以 x64 處理器或ARM64EC為目標之編譯的整數常值 100。 否則為未定義。_MANAGED
設定編譯/clr
程式選項時定義為 1。 否則為未定義。_MSC_BUILD
定義為整數常值,其中包含編譯程式版本號碼的修訂編號專案。 修訂編號是句點分隔版本號碼的最後一個專案。 例如,如果Microsoft C/C++ 編譯程式的版本號碼是 15.00.20706.01,巨集_MSC_BUILD
就是 1。 這個巨集一律會定義。_MSC_EXTENSIONS
如果已/Ze
設定預設的 [啟用語言延伸模組] 編譯程式選項, 則定義為1。 否則為未定義。_MSC_FULL_VER
定義為整數常值,以編碼編譯程式版本號碼的主要、次要和組建編號專案。 主要數位是句點分隔版本號碼的第一個專案,次要數位是第二個專案,而組建編號則是第三個元素。例如,如果Microsoft C/C++ 編譯程式版本為 19.39.33519,
_MSC_FULL_VER
則為 193933519。 在命令行輸入cl /?
,以檢視編譯程式的版本號碼。 這個巨集一律會定義。 如需編譯程式版本設定的詳細資訊,請參閱 從Visual Studio 2017開始C++編譯程式版本控制 ,特別是 從Visual Studio 2017 開始的服務版本,以取得Visual Studio 2019 16.8、16.9、16.10和16.11的詳細資訊,這些版本需要_MSC_FULL_VER
將它們分開。_MSC_VER
定義為整數常值,以編碼編譯程式版本號碼的主要和次要數字專案。 主要數位是句點分隔版本號碼的第一個專案,而次要數位則是第二個專案。 例如,如果Microsoft C/C++編譯程式的版本號碼是 17.00.51106.1,則 的值_MSC_VER
是 1700。 在命令行輸入cl /?
,以檢視編譯程式的版本號碼。 這個巨集一律會定義。若要在指定的 Visual Studio 或更新版本中測試編譯程式版本或更新,請使用
>=
運算符。 您可以在條件式指示詞中使用它來比較_MSC_VER
該已知版本。 如果您有數個互斥的版本要比較,請依版本號碼的遞減順序排序您的比較。 例如,此程式代碼會檢查 Visual Studio 2017 和更新版本中發行的編譯程式。 接下來,它會檢查在Visual Studio 2015中或之後發行的編譯程式。 然後它會檢查 Visual Studio 2015 之前發行的所有編譯程式:#if _MSC_VER >= 1910 // . . . #elif _MSC_VER >= 1900 // . . . #else // . . . #endif
如需 Visual Studio 2019 16.8 和 16.9 和 16.10 和 16.11 的詳細資訊,這些版本共用相同的主要和次要版本(因此 具有相同
_MSC_VER
的值),請參閱 從 Visual Studio 2017 開始的服務版本。如需編譯程式版本設定歷程記錄及其對應之 Visual Studio 版本號碼的詳細資訊,請參閱 編譯程式版本設定C++。 此外, Microsoft C++ 小組部落格上的 Visual C++ 編譯程式版本 。
_MSVC_LANG
定義為整數常值,指定編譯程式目標C++語言標準。 只有編譯為C++的程序代碼才會加以設定。 巨集預設為整數常值201402L
,或指定編譯程序選項時/std:c++14
。 如果指定編譯程式選項,/std:c++17
巨集就會設定為201703L
。 如果指定編譯程式選項,/std:c++20
巨集就會設定為202002L
。 當指定選項時/std:c++latest
,它會設定為較高的未指定值。 否則,巨集是未定義的。 從_MSVC_LANG
Visual Studio 2015 Update 3 開始,即可使用巨集和/std
(指定語言標準版本) 編譯程式選項。__MSVC_RUNTIME_CHECKS
當其中/RTC
一個編譯程式選項設定時定義為 1。 否則為未定義。_MSVC_TRADITIONAL
:- 從 Visual Studio 2017 15.8 版開始提供:設定預處理器一致性模式
/experimental:preprocessor
編譯程式選項時定義為 0。 默認定義為 1,或設定編譯程式選項時/experimental:preprocessor-
,表示傳統預處理器正在使用中。 - 從 Visual Studio 2019 16.5 版開始提供:設定預處理器一致性模式
/Zc:preprocessor
編譯程式選項時定義為 0。 默認定義為 1,或設定編譯程式選項時/Zc:preprocessor-
,表示傳統預處理器正在使用中(基本上,/Zc:preprocessor
取代已被/experimental:preprocessor
取代的 )。
#if !defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL // Logic using the traditional preprocessor #else // Logic using cross-platform compatible preprocessor #endif
- 從 Visual Studio 2017 15.8 版開始提供:設定預處理器一致性模式
_MT
當指定 或/MDd
(多線程 DLL) 或/MT
/MTd
(多線程) 時/MD
,定義為 1。 否則為未定義。_NATIVE_WCHAR_T_DEFINED
設定編譯/Zc:wchar_t
程式選項時定義為 1。 否則為未定義。_OPENMP
如果/openmp
已設定 [啟用 OpenMP 2.0 支援] 編譯程式選項,則定義為整數常值200203。 這個值代表 MSVC 所實作之 OpenMP 規格的日期。 否則為未定義。// _OPENMP_dir.cpp // compile with: /openmp #include <stdio.h> int main() { printf("%d\n", _OPENMP); }
_PREFAST_
設定編譯/analyze
程式選項時定義為 1。 否則為未定義。__SANITIZE_ADDRESS__
從 Visual Studio 2019 16.9 版開始提供。 設定編譯/fsanitize=address
程式選項時定義為 1。 否則為未定義。__TIMESTAMP__
定義為字串常值,其中包含目前原始程式檔上次修改的日期和時間,例如CRTasctime
函式所傳回的縮寫常數長度表單。Fri 19 Aug 13:32:58 2016
這個巨集一律會定義。_VC_NODEFAULTLIB
當設定 [省略默認連結庫名稱] 編譯程式選項時/Zl
,定義為 1。 否則為未定義。_WCHAR_T_DEFINED
設定預設/Zc:wchar_t
編譯程式選項時定義為 1。_WCHAR_T_DEFINED
巨集已定義,但如果已設定編譯程式選項,且wchar_t
定義於專案中包含的系統頭檔中,則巨集沒有值/Zc:wchar_t-
。 否則為未定義。_WIN32
當編譯目標為 32 位 ARM、64 位 ARM、x86 或 x64 時,定義為 1。 否則為未定義。_WIN64
當編譯目標為 64 位 ARM 或 x64 時,定義為 1。 否則為未定義。_WINRT_DLL
當編譯為 C++ 且/ZW
已設定 [Windows 執行階段 編譯] 和/LD
或/LDd
編譯程式選項時,定義為 1。 否則為未定義。
編譯程式不會預先定義識別 ATL 或 MFC 連結庫版本的預處理器巨集。 ATL 和 MFC 連結庫標頭會在內部定義這些版本巨集。 在包含必要標頭之前,它們未定義於預處理器指示詞中。
_ATL_VER
在中<atldef.h>
定義為編碼 ATL 版本號碼的整數常值。_MFC_VER
在中<afxver_.h>
定義為編碼 MFC 版本號碼的整數常值。