Chex常数型
我写了以下c代码:
#include int main () { printf("%d\n", -1 >> 8); return 0; }
我使用-m32标志在x86_64上使用gcc 4.6.3编译此代码。 我按照我的预期打印出-1,使用二进制补码表示算术运算得到-1。
现在,如果我改写
printf("%d\n", 0xFFFFFFFF >> 8);
我得到16777215.我本来期望这个常量被解释为一个int(有符号),然后转换为算术,这将再次导致-1。 我查看了最新的C标准,我似乎无法理解为什么会这样。 有任何想法吗?
根据C99标准(6.4.4.1),hex常量将是此列表中可以表示它们的第一个类型:
int unsigned int long int unsigned long int long long int unsigned long long int
hex文字0xFFFFFFFF
不适合int
(可以将值-0x80000000
为0x7FFFFFFF
),但是适合unsigned int
,因此其类型将是无符号的。 将无符号值0xFFFFFFFF
右移8可得到16777215
。
未修饰的整数文字具有不同的类型,具体取决于它们是否为十进制(C11中的6.4.4.1/5,C ++ 11中的表6):
-
十进制文字,即
[1-9][0-9]*
,始终是有符号的。 -
hex和八进制文字是有符号或无符号的。 如果有符号类型的值很大,但又小到足以适合相同宽度的无符号类型,则它将是无符号的。 (这是你的hex常数会发生的事情。)
右移负整数是实现定义的,你碰巧得到了符号扩展。 右移无符号值简单除以2。