我想完全理解C++编译器如何处理超过最大可能数的枚举,即包含-1和UINT64_MAX同时,即
enum A {
X = -1,
Y = UINT64_MAX
};
Run Code Online (Sandbox Code Playgroud)
首先,我认为编译器不接受此代码.实际上它enum被替换时不编译enum 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;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
X unsigned: 18446744073709551615, signed: -1
Y unsigned: 18446744073709551615, signed: -1
(X == XX) == 1
(X == Y) == 0
Run Code Online (Sandbox Code Playgroud)
现在我很困惑.显然,X和Y代表相同的数字,但它们仍然是可区分的,即比较X == Y是错误的(但X=XX实际上是真的).这里发生了什么?
我知道,更好的方法是不使用旧的enum,而是新的enum class.但仍然enum被广泛使用,我想了解这里发生了什么.
Bat*_*eba 10
您的编译器很可能使用128位有符号整数类型作为支持类型,与C++标准一致.
亲眼看看吧
std::cout << sizeof(std::underlying_type<A>::type);
Run Code Online (Sandbox Code Playgroud)
链接:https://ideone.com/z4K0rz,输出16.
您观察到的输出与将其转换为64位无符号类型的缩小一致.