常量整数提升规则

Constant integer promotion rules?

本文关键字:规则 整数 常量      更新时间:2023-10-16

为了提供一点背景(与下面的问题无关),在C++11中,我注意到了一个缩小范围的问题:

int foo[] = { 0xFFFFFFFF };

由于0xFFFFFFFFunsigned int,因此无法编译(缩小转换范围)。但是,我看到过签署0xFF的情况。

我已经研究了整数提升规则,但这主要是在左值的上下文中,而不是右值/常量。编译器如何确定常量的类型(没有文字后缀)?有没有文档或一个漂亮的小表格/"备忘单"来显示这方面的规则?我甚至不确定它叫什么,否则我会试图在C++11标准中自己找到它。

提前谢谢。

标准中有一个表,在cppreference.com上复制:http://en.cppreference.com/w/cpp/language/integer_literal

特别是,没有后缀的十六进制或八进制整数文字被认为是以下列表中可以表示其值的第一种类型:

int
unsigned int
long int
unsigned long int
long long int
unsigned long long int

如果int是32位长,则0xFFFFFFFF对于int来说太大,因此选择unsigned int。但是0xFF很适合int,所以int是。

在C中被称为整数常量的东西在C++中被称作整数值。C++标准草案2.14.2integer literals6中包含了用于确定integer literals类型的规则,其中表示:

整数文本的类型是相应列表的第一个在表6中可以表示其值。

对于没有后缀的八进制或十六进制常量,表的顺序如下:

int
unsigned int
long int
unsigned long int
long long int
unsigned long long int

因此,0xFF可以表示为int,而第一个可以表示0xFFFFFFFF的类型将是unsigned int

十进制常数的顺序如下:

int
long int
long long int

正如我们所看到的,十六进制和八进制文字的行为不同,我们可以看到C99有相同的表。国际标准——程序设计语言——C的基本原理如下:

与十进制常量不同,八进制和十六进制常量太大,无法如果在该类型的范围内,则be-ints被类型化为无符号int,因为它们更有可能代表比特模式或掩码通常最好将其视为无符号数字,而不是"实数"。

cpppreference integer literal部分还在literal的类型子部分中引用表6

0xFF从不为负数。这是255的另一种书写方式。(其类型为int)。

CCD_ 19是一个大的正数。[lex.icon]下有一个表,用于指定整数常量的类型。对于没有后缀的十六进制常量,它是以下列表中第一个可以容纳该大正数的类型:intunsigned intlong intunsigned long intlong long intunsigned long long int。实现可能会将自定义类型添加到此列表中。