/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++ требует, чтобы базовый тип перечисления был достаточно велик для хранения всех перечислителей, объявленных в нем. Достаточно крупные перечислители могут задать базовый enum
unsigned int
тип для , long long
или unsigned long long
. Ранее такие типы перечисления всегда имели базовый тип int
в компиляторе Майкрософт независимо от значений перечислителя.
Стандарт C++ также указывает, что в определении перечисления, которое не имеет фиксированного базового типа, типы перечислителей определяются их инициализаторами. Или для перечислителей без инициализатора по типу предыдущего перечислителя (учет переполнения). Ранее такие перечислители всегда были даны выводимый тип перечисления с заполнителем базового типа (обычно int
).
В версиях Visual Studio до Visual Studio 2022 версии 17.4 компилятор C++ не правильно определил базовый тип неуправляемого перечисления без фиксированного базового типа. Компилятор также не правильно моделировал типы перечислителей. Он может предположить неправильный тип перечисления без фиксированного базового типа перед закрывающей скобкой перечисления. В разделе /Zc:enumTypes
компилятор правильно реализует стандартное поведение.
Пример. Базовый тип без 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:enumTypes
A
был тип Enum
перечисления с выведенным базовым типом int
и инициализирован B
с помощью sizeof(Enum)
или 4.
Установка параметра компилятора в Visual Studio
Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.
Перейдите на страницу свойств Свойства конфигурации>C/C++>Командная строка.
В дополнительных параметрах добавьте
/Zc:enumTypes
или/Zc:enumTypes-
. Нажмите кнопку "ОК" или "Применить", чтобы сохранить изменения.
См. также
/Zc
(Соответствие)
/std
(определение стандартной версии языка)