【问题标题】:Underlying type of an unscoped enum?无范围枚举的基础类型?
【发布时间】:2019-08-29 16:39:51
【问题描述】:

我在 Visual Studio 2013(调试/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++ 标准 (Standard C++ 7.2/5),这是无效的 c++ 行为。在这种情况下,我不应该被要求显式定义底层类型,因为枚举器的值不适合 intunsigned int

所以:

  1. 这是 Visual Studio 2013 众所周知的限制吗(可能其他版本会受到影响)?
  2. 有没有办法强制编译器为 c++98 风格的枚举使用正确的底层类型?还是我需要切换到具有固定类型的 c++11 表示法?

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

【问题讨论】:

  • 最新的 VC 编译器给出了相同的 result.gcc 和 clang - 8 和 8(如预期的那样)。看起来像一个 VC 错误
  • 在 MSVC 上打印 V 会得到 -1,奇怪。
  • 没有警告 /Wall/permissive- 与 VS 2017 (15.9)。您应该将此作为错误提交到 VS Connect
  • 差别不大,但使用current draft 通常是个好主意。

标签: c++ visual-studio-2013


【解决方案1】:

参考说明如下(重要部分加粗):

声明一个无范围的枚举类型,其基础类型不是 固定(在这种情况下,基础类型是实现定义的 可以表示所有枚举数值的整数类型;这种类型是 不大于 int 除非枚举数的值不能放入 整数或无符号整数。如果 enumerator-list 为空,则底层 type 就好像枚举有一个值为 0 的枚举数)。

无范围枚举类型的值可以隐式转换为 整数类型。如果基础类型不固定,值为 可转换为以下列表中能够容纳的第一种类型 它们的整个取值范围:int、unsigned int、long、unsigned long、long long 或 unsigned long long。如果基础类型是固定的,则 值可以转换为其提升的基础类型。

综合起来,很明显这是 的一个错误(可能在某个时候引入)。更糟糕的是,它有点对此保持沉默。

【讨论】:

    猜你喜欢
    • 2019-06-15
    • 2022-01-07
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2012-03-09
    • 2010-10-25
    • 1970-01-01
    相关资源
    最近更新 更多