【问题标题】:enums exceeding the size of the largest number type超出最大数字类型大小的枚举
【发布时间】:2019-01-04 14:24:00
【问题描述】:

我想完全了解 C++ 编译器如何处理超出最大可能数的枚举,即同时包含 -1UINT64_MAX,即

enum A {
    X = -1,
    Y = UINT64_MAX
};

首先我认为编译器不会接受此代码。实际上当enumenum class替换时它不会编译,但是上面的例子编译。根据我们对底层类型的标准:

声明一个无作用域的枚举类型,其基础类型不固定(在这种情况下,基础类型是实现定义的整数类型,可以表示所有枚举器值;此类型不大于 int,除非枚举器的值不能适合 int 或 unsigned int。如果 enumerator-list 为空,则基础类型就好像枚举有一个值为 0 的枚举器)。 (https://en.cppreference.com/w/cpp/language/enum)

但这对我的例子意味着什么?

我写了一个小示例程序来看看会发生什么:

#include <iostream>
#include <cstdint>

enum A {
    X = -1,
    XX = -1,
    Y = UINT64_MAX
};

int main()
{

    std::cout << "X unsigned: " << (uint64_t)(X) << ", signed: " << (int64_t)(X) << std::endl;
    std::cout << "Y unsigned: " << (uint64_t)(Y) << ", signed: " << (int64_t)(Y) << std::endl;

    std::cout << "(X == XX) == " << (X == XX) << std::endl;
    std::cout << "(X == Y) == " << (X == Y) << std::endl;
}

输出是:

X unsigned: 18446744073709551615, signed: -1
Y unsigned: 18446744073709551615, signed: -1
(X == XX) == 1
(X == Y) == 0

现在我很困惑。显然,X 和 Y 代表同一个数字,但它们仍然是可区分的,即比较 X == Y 是假的(但 X=XX 实际上是真的)。这里发生了什么?

我知道,更好的方法不是使用旧的enum,而是使用新的enum class。 但是enum 仍然被广泛使用,我想了解这里发生了什么。

【问题讨论】:

  • 你问的是C还是C++?
  • @melpomene C 没有enum class 所以我认为可以肯定地假设我们只处理C++。甚至标签也匹配它。标题似乎只是一个疏忽。
  • @melpomene 查看标签,它是 C 风格的 C++ 用法 enum(而不是 enum class
  • 它不可重现:ideone.com/zTP38z
  • 您平台上的sizeof(A) 是什么? 64 位不一定是每个平台上最大的整数类型。

标签: c++ enums


【解决方案1】:

您的编译器很可能使用 128 位有符号整数类型作为支持类型,与 C++ 标准一致。

自己看看

std::cout << sizeof(std::underlying_type<A>::type);

链接:https://ideone.com/z4K0rz,输出 16。

您观察到的输出与将其缩小到 64 位无符号类型的转换一致。

【讨论】:

  • 嗯 - 想为此写一个笑话评论 - 现在证明这是事实......太糟糕了标准化团队没有与其他人一起定义 (u)int128_t - 或添加至少,当 64 位系统在世界范围内广泛传播时......
【解决方案2】:

您看到的是类型转换的效果,而不是enum。您的输出取决于您如何转换值。

试试这个:它的输出和你的一样,没有enums。

#include <iostream>
#include <cstdint>

int main()
{

    std::cout << "X unsigned: " << (uint64_t)(-1) << ", signed: " << (int64_t)(-1) << std::endl;
    return 0;
}

输出是:

X unsigned: 18446744073709551615, signed: -1

【讨论】:

  • 问题是关于枚举。您的示例所做的只是两次打印相同的内容,除了文本中的字母不同之外,它们当然会产生相同的结果。如果我复制/粘贴一行代码,我希望第二个代码和第一个代码一样。
  • 虽然演员表有一定的道理,但它并没有解释问题中更重要的部分 X 如何不等于 Y...
  • @RetiredNinja,是的,确实如此。该问题的标题是超出最大数字类型大小的枚举。我删除了多余的线。 OP 问了我,我引用了Obviously, X and Y represent the same number, but they are still distinguishable, ...。 OP 在他的输出中显示的唯一差异只是他如何投射的结果。
猜你喜欢
  • 1970-01-01
  • 2021-09-19
  • 2023-02-08
  • 1970-01-01
  • 2016-02-27
  • 2011-06-20
  • 2019-07-21
  • 2010-09-14
相关资源
最近更新 更多