枚举超过了最大数字类型的大小

enums exceeding the size of the largest number type

本文关键字:类型 数字 枚举 过了      更新时间:2023-10-16

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

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

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

声明其基础类型不是固定的无范围枚举类型(在这种情况下,基础类型是实现定义的整数类型,可以表示所有枚举器值;除非枚举器的值不能容纳在int或无符号int中,否则此类型不大于int。如果枚举器列表为空,则基础类型就像枚举有一个值为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位无符号类型的转换一致。

您看到的是类型转换的影响,而不是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