/Zc:enumTypes (Включить вычет типов перечисления)

Параметр /Zc:enumTypes компилятора позволяет C++ соответствовать enum базовому типу и вычету типов перечислителя.

Синтаксис

/Zc:enumTypes[-]

Замечания

Параметр /Zc:enumTypes компилятора реализует поведение, соответствующее стандарту C++ для вычета базовых типов перечисления и типов перечислителей.

Этот /Zc:enumTypes параметр доступен в Visual Studio 2022 версии 17.4. Этот параметр отключен по умолчанию и не включен /permissive-. Чтобы явно отключить этот параметр, используйте /Zc:enumTypes-.

При включении этот /Zc:enumTypes параметр является потенциальным источником и двоичным критическим изменением. При включении параметра соответствия /Zc:enumTypes некоторые типы перечислений изменяют размер. Некоторые заголовки пакета SDK для Windows включают такие определения перечисления.

Стандарт C++ требует, чтобы базовый тип перечисления был достаточно велик для хранения всех перечислителей, объявленных в нем. Достаточно крупные перечислители могут задать базовый enumunsigned intтип для , long longили unsigned long long. Ранее такие типы перечисления всегда имели базовый тип int в компиляторе Майкрософт независимо от значений перечислителя.

Стандарт C++ также указывает, что в определении перечисления, которое не имеет фиксированного базового типа, типы перечислителей определяются их инициализаторами. Или для перечислителей без инициализатора по типу предыдущего перечислителя (учет переполнения). Ранее такие перечислители всегда были даны выводимый тип перечисления с заполнителем базового типа (обычно int).

В версиях Visual Studio до Visual Studio 2022 версии 17.4 компилятор C++ неправильно определил базовый тип перечисления un область d без фиксированного базового типа. Компилятор также не правильно моделировал типы перечислителей. Он может предположить неправильный тип перечисления без фиксированного базового типа перед закрывающей скобкой перечисления. В разделе /Zc:enumTypesкомпилятор правильно реализует стандартное поведение.

Пример. Базовый тип un область d enum без фиксированного типа

enum Unsigned
{
    A = 0xFFFFFFFF // Value 'A' does not fit in 'int'.
};

// Previously, this static_assert failed. It passes with /Zc:enumTypes.
static_assert(std::is_same_v<std::underlying_type_t<Unsigned>, unsigned int>);

template <typename T>
void f(T x)
{
}

int main()
{
    // Previously called f<int>, now calls f<unsigned int>.
    f(+A);
}

// Previously, this enum would have an underlying type of `int`,
// but Standard C++ requires this to have a 64-bit underlying type.
// The /Zc:enumTypes option changes the size of this enum from 4 to 8,
// which could impact binary compatibility with code compiled with an
// earlier compiler version, or without the switch.
enum Changed
{
    X = -1,
    Y = 0xFFFFFFFF
};

Пример. Перечислители в определении enum без фиксированного базового типа

enum Enum {
    A = 'A',
    B = sizeof(A)
};

static_assert(B == 1); // previously failed, now succeeds under /Zc:enumTypes

В этом примере перечислитель A должен иметь тип char до закрывающей скобки перечисления, поэтому B его следует инициализировать с помощью sizeof(char). Перед исправлением /Zc:enumTypesA был тип Enum перечисления с выведенным базовым типом intи инициализирован B с помощью sizeof(Enum)или 4.

Установка параметра компилятора в Visual Studio

  1. Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.

  2. Перейдите на страницу свойств Свойства конфигурации>C/C++>Командная строка.

  3. В дополнительных параметрах добавьте /Zc:enumTypes или /Zc:enumTypes-. Нажмите кнопку "ОК" или "Применить", чтобы сохранить изменения.

См. также

/Zc (Соответствие)
/std (определение стандартной версии языка)