共用方式為


預先定義巨集

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-unaware operator 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。 否則為未定義。

  • _DEBUG當 設定、 /MDd/MTd 編譯程式選項時/LDd,定義為 1。 否則為未定義。

  • _DLL當設定 或 /MDd (多線程 DLL) 編譯程式選項時/MD,定義為 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:SSE22。 如果未 /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
    
  • _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__定義為字串常值,其中包含目前原始程式檔上次修改的日期和時間,例如CRT asctime 函式所傳回的縮寫常數長度表單。 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 版本號碼的整數常值。

另請參閱

巨集 (C/C++)
預處理器運算元
預處理器指示詞