/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选项后,一些枚举类型会改变大小。 一些 Windows SDK 标头包括此类枚举定义。

C++ 标准要求枚举的基础类型足够大,足以容纳其中声明的所有枚举器。 足够大的枚举器可以将 enum 的基础类型设置为 unsigned intlong longunsigned long long。 以前,这种枚举类型在 Microsoft 编译器中始终具有基础类型int,无需考虑枚举器的值。

C++ 标准也指定,在没有固定基础类型的枚举定义中,枚举器的类型由其初始值设定项确定。 或者,对于没有初始值设定项的枚举器,由上一个枚举器的类型确定(考虑到溢出)。 以前,此类枚举器始终被赋予枚举的推导类型,带基础类型的占位符(通常为 int)。

在 Visual Studio 2022 版本 17.4 之前的 Visual Studio 版本中,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,推导的基本类型为 intB 使用 sizeof(Enum) 进行了初始化,或者是 4。

在 Visual Studio 中设置此编译器选项

  1. 打开项目的“属性页” 对话框。 有关详细信息,请参阅在 Visual Studio 中设置 C++ 编译器和生成属性

  2. 选择“配置属性”>“C/C++”>“命令行”属性页

  3. 其他选项中添加 /Zc:enumTypes/Zc:enumTypes-。 选择“确定”或“应用”以保存更改。

另请参阅

/Zc(一致性)
/std(指定语言标准版本)