【发布时间】:2019-01-04 14:24:00
【问题描述】:
我想完全了解 C++ 编译器如何处理超出最大可能数的枚举,即同时包含 -1 和 UINT64_MAX,即
enum A {
X = -1,
Y = UINT64_MAX
};
首先我认为编译器不会接受此代码。实际上当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;
}
输出是:
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 位不一定是每个平台上最大的整数类型。