为了给出一些背景(与之后的问题无关),在C ++ 11中,我注意到一个缩小的问题:
int foo[] = { 0xFFFFFFFF };
由于0xFFFFFFFF
是unsigned int
,因此无法编译(缩小转化)。但是,我已经看到0xFF
已签名的案例。
我查看了整数提升规则,但这主要是在左值而不是右值/常量的上下文中。编译器如何确定常量类型(没有文字后缀)?有没有文件或一张漂亮的小桌子/"备忘单"那显示了这个规则?我甚至不确定这是什么,否则我自己试图在C ++ 11标准中找到它。
提前致谢。
答案 0 :(得分:12)
标准中有一个表格,在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
如果0xFFFFFFFF
长度为32位, int
对于int
而言太大,因此选择unsigned int
。但是0xFF
很适合int
,所以int
就是这样。
答案 1 :(得分:6)
C中称为整数常量的内容在C ++中称为整数文字。用于确定整数文字类型的规则包含在draft C++ standard部分2.14.2
整数文字表6
中:
整数文字的类型是相应列表的第一个 在表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
正如我们所看到的,十六进制和八进制文字的行为不同,我们可以看到that C99 has the same table。 Rationale for International Standard—Programming Languages—C说明了以下内容:
与十进制常量不同,八进制和十六进制常量太大 如果在该类型的范围内,则in int被键入为unsigned int,因为 它们更有可能代表位模式或掩码 通常最好被视为无符号,而不是“真实”数字。
cppreference integer literal section还引用了文字子类型中的表6
。
答案 2 :(得分:2)
0xFF
永远不会消极。这是写255
的另一种方式。 (它的类型为int
)。
0xFFFFFFFF
是一个很大的正数。 [lex.icon]下有一个表,指定整数常量的类型。对于没有后缀的十六进制常量,它是以下列表中可以容纳该大正数的第一个类型:int
,unsigned int
,long int
,unsigned long int
,{{ 1}},long long int
。该实现可能会在此列表中添加自定义类型。