我想完全了解 C++ 编译器如何处理超出最大可能数字的枚举,即同时包含 -1
和 UINT64_MAX
,即
enum A {
X = -1,
Y = UINT64_MAX
};
首先我认为编译器不会接受此代码。实际上,当 enum
被 enum class
替换时它不会编译,但上面的示例可以编译。根据我们对底层类型的标准:
Declares an unscoped enumeration type whose underlying type is not fixed (in this case, the underlying type is an implementation-defined integral type that can represent all enumerator values; this type is not larger than int unless the value of an enumerator cannot fit in an int or unsigned int. If the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value 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
仍然被广泛使用,我想了解这里发生了什么。
最佳答案
您的编译器很可能使用 128 位有符号整数类型作为支持类型,与 C++ 标准一致。
自己看看
std::cout << sizeof(std::underlying_type<A>::type);
链接:https://ideone.com/z4K0rz ,输出 16。
您观察到的输出与将其缩小到 64 位无符号类型的转换是一致的。
关于c++ - 超出最大数字类型大小的枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54040803/