Предустановленные макросы

Компилятор Microsoft C/C++ (MSVC) определяет определенные макросы препроцессора в зависимости от языка (C или C++), целевого объекта компиляции и выбранных параметров компилятора.

MSVC поддерживает предопределенные макросы препроцессора, необходимые стандартам ANSI/ISO C99, C11 и C17, а также стандартам ISO C++14, C++17 и C++20. Эта реализация также поддерживает несколько дополнительных макросов препроцессора, характерных для систем Майкрософт.

Некоторые макросы определяются только для конкретных сред сборки или параметров компилятора. Если не указано иное, макросы определяются по всей единице трансляции, как если бы они были указаны в качестве аргументов параметра компилятора /D. При определении препроцессор развертывает макросы перед компиляцией. Предопределенные макросы не принимают аргументы и не могут быть определены повторно.

Стандартный предопределенный идентификатор

Компилятор поддерживает этот предопределенный идентификатор, описанный стандартами ISO C99 и ISO C++11.

  • __func__ — неполное имя включающей функции без дополнений, записываемое в виде локального для функции массива static const с элементами char.

    void example(){
        printf("%s\n", __func__);
    } // prints "example"
    

Стандартные предопределенные макросы

Компилятор поддерживает эти предопределенные макросы, описанные стандартами ISO C99, C11, C17 и ISO C++17.

  • __cplusplus — определяется как целочисленное литеральное значение, если единица трансляции компилируется как C++. В противном случае — не определяется.

  • __DATE__ — дата компиляции текущего файла исходного кода. Дата — строковой литерал постоянной длины в формате ммм дд гггг. Название месяца ммм совпадает с сокращенным названием месяца, созданным функцией asctime библиотеки времени выполнения C (CRT). Первый символ даты дд — это пробел, если значение меньше 10. Этот макрос определяется всегда. Этот макрос определяется всегда.

  • __FILE__ — имя текущего файла исходного кода. __FILE__ развертывается в литерал строки символов. Чтобы убедиться, что отображается полный путь к файлу, используйте /FC (полный путь к файлу исходного кода в диагностике). Этот макрос определяется всегда.

  • __LINE__ определяется как целочисленный номер строки в текущем файле исходного кода. Значение этого макроса можно изменить с помощью директивы #line . Целочисленный тип значения __LINE__ может отличаться в зависимости от контекста. Этот макрос определяется всегда.

  • __STDC__ Определяется как 1 при компиляции как C и указан параметр компилятора /Za . Начиная с Visual Studio 2022 версии 17.2, он определяется как 1 при компиляции как C и /std:c11/std:c17 указан параметр компилятора. В противном случае — не определяется.

  • __STDC_HOSTED__ определяется как 1, если реализация является размещенной реализацией, полностью поддерживающей необходимую стандартную библиотеку. В противном случае определяется как 0.

  • __STDC_NO_ATOMICS__ — определяется как 1, если реализация не поддерживает необязательные стандартные атомарные элементы. Реализация MSVC определяет его как 1 при компиляции в виде C, а также одного из вариантов /std C11 или C17.

  • __STDC_NO_COMPLEX__ — определяется как 1, если реализация не поддерживает необязательные стандартные комплексные числа. Реализация MSVC определяет его как 1 при компиляции в виде C, а также одного из вариантов /std C11 или C17.

  • __STDC_NO_THREADS__ — определяется как 1, если реализация не поддерживает необязательные стандартные потоки. Реализация MSVC определяет его как 1 при компиляции в виде C, а также одного из вариантов /std C11 или C17.

  • __STDC_NO_VLA__ — определяется как 1, если реализация не поддерживает стандартные массивы переменной длины. Реализация MSVC определяет его как 1 при компиляции в виде C, а также одного из вариантов /std C11 или C17.

  • __STDC_VERSION__ — определяется при компиляции в виде C, а также одного из вариантов /std C11 или C17. Он разворачивается в 201112L для /std:c11 и в 201710L для /std:c17.

  • __STDCPP_DEFAULT_NEW_ALIGNMENT__ При /std:c17 указании или более поздней версии этот макрос расширяется до size_t литерала, который имеет значение выравнивания, гарантированное вызовом выравнивания, не зная operator new. Более крупные выравнивания передаются в перегрузку с поддержкой выравнивания, например operator new(std::size_t, std::align_val_t). Дополнительные сведения см. в разделе /Zc:alignedNew (выделение на языке C++17 с превышением выравнивания).

  • __STDCPP_THREADS__ определяется как 1, только если программа может иметь только один поток выполнения и cкомпилирована как C++. В противном случае — не определяется.

  • __TIME__ — время, в течение которого выполняется преобразование предварительно обработанной единицы трансляции. Время представляет собой литерал строки символов в форме чч:мм:сс, который совпадает со временем, возвращаемым функцией asctime CRT. Этот макрос определяется всегда.

Предопределенные макросы, предназначенные специально для систем Майкрософт

MSVC поддерживает другие предопределенные макросы:

  • __ATOM__ — определяется как 1, если задан параметр компилятора /favor:ATOM и компилятор имеет целевую платформу x86 или x64. В противном случае — не определяется.

  • __AVX__ — определяется как 1, если заданы параметры компилятора /arch:AVX, /arch:AVX2 или /arch:AVX512 и компилятор имеет целевую платформу x86 или x64. В противном случае — не определяется.

  • __AVX2__ — определяется как 1, если заданы параметры компилятора /arch:AVX2 или /arch:AVX512 и компилятор имеет целевую платформу x86 или x64. В противном случае — не определяется.

  • __AVX512BW__ — определяется как 1, если задан параметр компилятора /arch:AVX512 и компилятор имеет целевую платформу x86 или x64. В противном случае — не определяется.

  • __AVX512CD__ — определяется как 1, если задан параметр компилятора /arch:AVX512 и компилятор имеет целевую платформу x86 или x64. В противном случае — не определяется.

  • __AVX512DQ__ — определяется как 1, если задан параметр компилятора /arch:AVX512 и компилятор имеет целевую платформу x86 или x64. В противном случае — не определяется.

  • __AVX512F__ — определяется как 1, если задан параметр компилятора /arch:AVX512 и компилятор имеет целевую платформу x86 или x64. В противном случае — не определяется.

  • __AVX512VL__ — определяется как 1, если задан параметр компилятора /arch:AVX512 и компилятор имеет целевую платформу x86 или x64. В противном случае — не определяется.

  • _CHAR_UNSIGNED — определяется как 1, если по умолчанию используется тип char без знака. Это значение определяется, если задан параметр компилятора /J (по умолчанию тип char без знака). В противном случае — не определяется.

  • __CLR_VER определяется как целочисленный литерал, представляющий версию среды 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 — определяется как 1, если задан параметр компилятора /guard:cf (Включение защиты потока управления). В противном случае — не определяется.

  • __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 — определяется как целочисленное литеральное значение 200406 при компиляции в виде C++ и при заданном параметре компилятора /clr. В противном случае — не определяется. Когда __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 — определяется как целочисленное литеральное значение 201009 при компиляции в виде C++ и при заданном параметре компилятора /ZW (Компиляция для среды выполнения Windows). В противном случае — не определяется.

  • _CPPRTTI — определяется как 1, если задан параметр компилятора /GR (Включение сведений о типе во время выполнения). В противном случае — не определяется.

  • _CPPUNWIND — определяется как 1, если заданы какие-то из следующих параметров компилятора: /GX (Включить обработку исключений), /clr (Компиляция для среды CLR) или /EH (Модель обработки исключений). В противном случае — не определяется.

  • _DEBUG — определяется как 1, если заданы параметры компилятора /LDd, /MDd или /MTd. В противном случае — не определяется.

  • _DLL — определяется как 1, если заданы параметры компилятора /MD или /MDd (Многопоточная библиотека DLL). В противном случае — не определяется.

  • __FUNCDNAME__ определяется как строковый литерал, содержащий декорированное имя включающей функции. Макрос определен только в пределах функции. Макрос __FUNCDNAME__ не разворачивается, если используется параметр компилятора /EP или /P.

    В этом примере макросы __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__ определяется как строковый литерал, содержащий сигнатуру включающей функции. Макрос определен только в пределах функции. Макрос __FUNCSIG__ не разворачивается, если используется параметр компилятора /EP или /P. При компиляции для 64-разрядных целевых платформ по умолчанию используется соглашение о вызовах __cdecl. Пример использования см. в разделе для макроса __FUNCDNAME__.

  • __FUNCTION__ определяется как строковый литерал, содержащий недекорированное имя включающей функции. Макрос определен только в пределах функции. Макрос __FUNCTION__ не разворачивается, если используется параметр компилятора /EP или /P. Пример использования см. в разделе для макроса __FUNCDNAME__.

  • _INTEGRAL_MAX_BITS определяется как целочисленное литеральное значение 64, максимальный размер (в битах) для целочисленного типа без вектора. Этот макрос определяется всегда.

    // integral_max_bits.cpp
    #include <stdio.h>
    int main() {
        printf("%d\n", _INTEGRAL_MAX_BITS);
    }
    
  • __INTELLISENSE__ определяется как 1 во время прохода компилятором IntelliSense в интегрированной среде разработки Visual Studio. В противном случае — не определяется. Этот макрос можно использовать для защиты кода, который компилятор IntelliSense не понимает, или для переключения между сборкой и компилятором IntelliSense. Дополнительные сведения см. в разделе советы по устранению неполадок при медленной работе IntelliSense.

  • _ISO_VOLATILE — определяется как 1, если задан параметр компилятора /volatile:iso. В противном случае — не определяется.

  • _KERNEL_MODE — определяется как 1, если задан параметр компилятора /kernel (Создать двоичный файл режима ядра). В противном случае — не определяется.

  • _M_AMD64 Определяется как целочисленное литеральное значение 100 для компиляций, предназначенных для процессоров x64 или ARM64EC. В противном случае — не определяется.

  • _M_ARM определяется как целочисленное литеральное значение 7 для компиляций, предназначенных для процессоров ARM. Не определено для ARM64, ARM64EC и других целевых объектов.

  • _M_ARM_ARMV7VE — определяется как 1, если задан параметр компилятора /arch:ARMv7VE для компиляций под процессоры ARM. В противном случае — не определяется.

  • _M_ARM_FP — определяется как целочисленное литеральное значение, указывающее, какой параметр компилятора /arch был задан для целевых платформ на процессоре ARM. В противном случае — не определяется.

    • Значение в диапазоне 30–39, если не был указан параметр /arch для ARM, что означает, что была задана архитектура для ARM по умолчанию (VFPv3).

    • Значение в диапазоне 40–49, если было задано /arch:VFPv4.

    • Дополнительные сведения: /arch (ARM).

  • _M_ARM64 Определяется как 1 для компиляций, предназначенных для ARM64. В противном случае — не определяется.

  • _M_ARM64EC Определяется как 1 для компиляций, предназначенных для ARM64EC. В противном случае — не определяется.

  • _M_CEE — определяется как 001, если задан параметр компилятора /clr (Компиляция для среды CLR). В противном случае — не определяется.

  • _M_CEE_PURE объявлен нерекомендуемым начиная с Visual Studio 2015. Определяется как 001, если задан параметр компилятора /clr:pure. В противном случае — не определяется.

  • _M_CEE_SAFE объявлен нерекомендуемым начиная с Visual Studio 2015. Определяется как 001, если задан параметр компилятора /clr:safe. В противном случае — не определяется.

  • _M_FP_CONTRACT доступен начиная с Visual Studio 2022. Определяется как 1, если /fp:contract задан параметр или /fp:fast компилятор. В противном случае — не определяется.

  • _M_FP_EXCEPT — определяется как 1, если задан параметр компилятора /fp:except или /fp:strict. В противном случае — не определяется.

  • _M_FP_FAST — определяется как 1, если задан параметр компилятора /fp:fast. В противном случае — не определяется.

  • _M_FP_PRECISE — определяется как 1, если задан параметр компилятора /fp:precise. В противном случае — не определяется.

  • _M_FP_STRICT — определяется как 1, если задан параметр компилятора /fp:strict. В противном случае — не определяется.

  • _M_IX86 определяется как целочисленное литеральное значение 600 для компиляций, предназначенных для процессоров x86. Этот макрос не определяется для целевых объектов компиляции x64 или ARM.

  • _M_IX86_FP — определяется как целочисленное литеральное значение, указывающее заданный параметр компилятора /arch либо значение по умолчанию. Этот макрос всегда определяется, если целевым объектом компиляции является процессор x86. В противном случае — не определяется. Когда определен, значение равно:

    • 0, если задан параметр компилятора /arch:IA32.

    • 1, если задан параметр компилятора /arch:SSE.

    • 2, если задан параметр компилятора /arch:SSE2, /arch:AVX, /arch:AVX2 или /arch:AVX512. Это значение используется по умолчанию, если не был указан параметр компилятора /arch. Если указан /arch:AVX, также определяется макрос __AVX__. Если указан /arch:AVX2, также определяются __AVX__ и __AVX2__. Если указано /arch:AVX512, также определяются __AVX__, __AVX2__, __AVX512BW__, __AVX512CD__, __AVX512DQ__, __AVX512F__ и __AVX512VL__.

    • Дополнительные сведения: /arch (x86).

  • _M_X64 Определяется как целочисленное литеральное значение 100 для компиляций, предназначенных для процессоров x64 или ARM64EC. В противном случае — не определяется.

  • _MANAGED — определяется как 1, если задан параметр компилятора /clr. В противном случае — не определяется.

  • _MSC_BUILD определяется как целочисленный литерал, содержащий элемент номера редакции номера версии компилятора. Номер редакции является последним элементом номера версии с разделителями периода. Например, если номер версии компилятора Microsoft C/C++ равен 15.00.20706.01, _MSC_BUILD макрос равен 1. Этот макрос определяется всегда.

  • _MSC_EXTENSIONS — определяется как 1, если задан включенный по умолчанию параметр компилятора /Ze (Включить расширения языка). В противном случае — не определяется.

  • _MSC_FULL_VER определяется как целочисленный литерал, кодирующий такие элементы номера версии компилятора, как основной номер версии, дополнительный номер версии и номер сборки. Основной номер — это первый элемент номера версии с разделителями точками, дополнительный номер — второй элемент, а номер сборки — третий.

    Например, если версия компилятора Microsoft C/C++ имеет значение 19.39.33519, _MSC_FULL_VER 193933519. Для просмотра номера версии компилятора введите cl /? в командной строке. Этот макрос определяется всегда. Дополнительные сведения об использовании версий компилятора см. в статье о версиях компилятора 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++". Кроме того, версия компилятора Visual C++ в блоге команды Microsoft C++.

  • _MSVC_LANG определяется как целочисленный литерал, указывающий стандарт языка C++, на который ориентируется компилятор. Он задается только в коде, компилируемом как C++. Этот макрос представляет собой целочисленное литеральное значение 201402L по умолчанию или при указании параметра компилятора /std:c++14. Макрос имеет значение 201703L, если указан параметр компилятора /std:c++17. Макрос имеет значение 202002L, если указан параметр компилятора /std:c++20. Если указан параметр /std:c++latest, макросу присваивается более высокое неопределенное значение. В противном случае макрос не определяется. Макрос _MSVC_LANG и параметр компилятора /std (Определить версию стандарта языка) доступны начиная с Visual Studio 2015 с обновлением 3.

  • __MSVC_RUNTIME_CHECKS — определяется как 1, если задан один из параметров компилятора /RTC. В противном случае — не определяется.

  • _MSVC_TRADITIONAL:

    • Доступно начиная с Visual Studio 2017 версии 15.8: определяется как 0 при установке параметра компилятора режима /experimental:preprocessor соответствия препроцессора. Определяется как 1 по умолчанию или при заданном параметре компилятора /experimental:preprocessor-, указывая на использование традиционного препроцессора.
    • Доступно начиная с Visual Studio 2019 версии 16.5: определяется как 0 при установке параметра компилятора режима /Zc:preprocessor соответствия препроцессора. Определяется как 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 — определяется как 1, если задан параметр /MD или /MDd (Многопоточная библиотека DLL) либо /MT или /MTd (Многопоточная библиотека). В противном случае — не определяется.

  • _NATIVE_WCHAR_T_DEFINED — определяется как 1, если задан параметр компилятора /Zc:wchar_t. В противном случае — не определяется.

  • _OPENMP — определяется как целочисленный литерал 200203, если задан параметр компилятора /openmp (Включить поддержку OpenMP 2.0). Это значение представляет дату спецификации OpenMP, реализуемой компилятором MSVC. В противном случае — не определяется.

    // _OPENMP_dir.cpp
    // compile with: /openmp
    #include <stdio.h>
    int main() {
        printf("%d\n", _OPENMP);
    }
    
  • _PREFAST_ — определяется как 1, если задан параметр компилятора /analyze. В противном случае — не определяется.

  • __SANITIZE_ADDRESS__ Доступно начиная с Visual Studio 2019 версии 16.9. Определяется как 1 при установке параметра компилятора /fsanitize=address . В противном случае — не определяется.

  • __TIMESTAMP__ — определяется как строковый литерал, содержащий дату и время последнего изменения текущего исходного файла в сокращенной форме с постоянной длиной, которые возвращаются функцией asctime библиотеки CRT, например: Fri 19 Aug 13:32:58 2016. Этот макрос определяется всегда.

  • _VC_NODEFAULTLIB — определяется как 1, если задан параметр компилятора /Zl (Пропускать имена стандартных библиотек). В противном случае — не определяется.

  • _WCHAR_T_DEFINED — определяется как 1, если задан параметр компилятора /Zc:wchar_t, используемый по умолчанию. Макрос _WCHAR_T_DEFINED определен, но не имеет значения, если задан параметр компилятора /Zc:wchar_t-, а в системном файле заголовка, включенном в ваш проект, определен параметр wchar_t. В противном случае — не определяется.

  • _WIN32 определяется как 1, если целевой объект компиляции — 32-разрядная архитектура ARM, 64-разрядная архитектура ARM, x86 или x64. В противном случае — не определяется.

  • _WIN64 определяется как 1, если целевой объект компиляции — 64-разрядная архитектура ARM или x64. В противном случае — не определяется.

  • _WINRT_DLL — определяется как 1 при компиляции в виде C++ и при заданных параметрах компилятора /ZW (Компиляция для среды выполнения Windows) и /LD или /LDd. В противном случае — не определяется.

Нет предопределенных компилятором макросов препроцессора, которые определяют версию библиотеки ATL или MFC. Заголовки библиотек ATL и MFC определяют эти макросы версий внутренним образом. Они не определены в директивах препроцессора, выполняемых до включения необходимого заголовка.

  • _ATL_VER — определяется в <atldef.h> как целочисленный литерал, который кодирует номер версии библиотеки ATL.

  • _MFC_VER — определяется в <afxver_.h> как целочисленный литерал, который кодирует номер версии библиотеки MFC.

См. также

Макросы (C/C++)
Операторы препроцессора
Директивы препроцессора