无作用域枚举的基础类型?

Underlying type of an unscoped enum?

本文关键字:类型 作用域 枚举      更新时间:2023-10-16

我在Visual Studio 2013(Debug/Win32编译)下观察到以下行为。请考虑以下 C++ 代码:

#include <iostream>
#include <climits>
int main(int argc, char *argv[])
{
enum { V = (unsigned long long)ULLONG_MAX } E;
std::cout << sizeof E << std::endl;
enum : unsigned long long { W = (unsigned long long)ULLONG_MAX } F;
std::cout << sizeof F << std::endl;
return 0;
}

编译后,这将导致:

$ ./enum.exe
4
8

如果我正确理解了 c++ 标准(标准 C++ 7.2/5),这是一个无效的 c++ 行为。在这种情况下,我不需要显式定义基础类型,因为枚举器的值无法容纳在intunsigned int中。

所以:

  1. 这是Visual Studio 2013的一个众所周知的限制(也许其他版本受到影响)?
  2. 有没有办法强制编译器为 c++98 样式枚举使用适当的底层类型?还是我需要切换到固定类型的 c++11 表示法?

更新:按照建议,我在以下位置报告了一个问题:

  • https://developercommunity.visualstudio.com/content/problem/524018/underlying-type-of-an-unscoped-enum.html

参考文献如下(重要部分加粗):

声明基础类型不是的无作用域枚举类型 fixed (在本例中,基础类型是实现定义的 可以表示所有枚举器值的整数类型;此类型是 不大于 int,除非枚举器的值无法容纳在 int 或无符号 int。如果枚举器列表为空,则基础 类型就像枚举具有值为 0 的单个枚举器一样)。

无作用域枚举类型的值可隐式转换为 积分类型。如果基础类型不固定,则值为 可转换为以下列表中的第一种类型,能够保持 它们的整个值范围:整数、无符号整数、长整型、无符号长整型、长整型 长,或无符号长长。如果基础类型是固定的,则 值可以转换为其提升的基础类型。

综上所述,很明显它是 msvc 的错误(可能在某个时候引入)。更糟糕的是,它对此保持沉默