我正在研究C ++标准n4713.pdf。考虑下面的代码:
#include
#include
enum UEn
{
EN_0,
EN_1,
EN_L = 0x7FFFFFFFFFFFFFFF // EN_L has type "long int"
}; // UEn has underlying type "unsigned long int"
int main()
{
long lng = 0x7FFFFFFFFFFFFFFF;
std::cout << std::boolalpha;
std::cout << "typeof(unsigned long == UEn):" << std::is_same::type>::value << std::endl; // Outputs "true"
std::cout << "sizeof(EN_L):" << sizeof(EN_L) << std::endl;
std::cout << "sizeof(unsigned):" << sizeof(unsigned) << std::endl;
std::cout << "sizeof(unsigned long):" << sizeof(unsigned long) << std::endl;
std::cout << "sizeof(unsigned long):" << sizeof(unsigned long long) << std::endl;
lng = EN_L + 1; // Invokes UB as EN_L is 0x7FFFFFFFFFFFFFFF and has type "long int"
return 0;
}
上面的代码输出(在g ++-8.1,Clang上测试):
typeof(unsigned long == UEn):true sizeof(EN_L):8 sizeof(unsigned):4 sizeof(unsigned long):8 sizeof(unsigned long):8
根据10.2p5节(10.2枚举声明):
在枚举说明符的右括号之后,每个枚举器都有
枚举的类型...如果基础类型不固定,则
闭括号前的每个枚举器的类型确定为
如下:
如果为枚举器指定了初始化程序,则
constant-expression应该是整数常量表达式(8.6)。如果
表达式具有无范围的枚举类型,枚举器具有
该枚举类型的基础类型,否则具有相同的值
类型作为表达式。
如果没有为第一个指定初始化程序
枚举数,其类型是未指定的带符号整数类型。
否则,枚举器的类型与
前面的枚举数,除非增量值无法表示
在那种类型的情况下,这种类型是未指定的整数类型
足以包含增加的值。如果不存在这样的类型,
该程序格式不正确。
此外,第10.2p7节规定:
对于基础类型不固定的枚举,基础
type是一个整数类型,可以表示所有枚举器值
在枚举中定义。如果没有整数类型可以代表所有
枚举值,则枚举格式不正确。它是
实现定义哪种整数类型用作基础
类型,但基础类型不得大于int
除非枚举数的值不能适合int或unsigned
因此,我有以下问题:
当UEn是类型unsigned long的整数常量,因此0x7FFFFFFFFFFFFFFF的类型也是{时,为什么枚举long int的基础类型是EN_L {1}}。这是编译器错误还是行为明确?
当标准说long int时,是否不应该暗示枚举数和枚举的整数类型也应该匹配?这两个彼此不同的原因可能是什么?