2013-05-07 39 views
1

我发现一些有线问题,当我尝试做32次左移时。测试函数中的代码应该打印出相同的结果0x0,但我得到了“ffffffff,0”。任何人都可以暗示代码有什么问题?谢谢!按位左移意外结果

int test(int n) { 
    int mask = ~0 << (32 + ~n + 1); 
    int mask1 = ~0 << (32 + ~0 + 1); 
    printf("%x, %x\n", mask, mask1); 
    return mask; 
} 

int main(){ 
    test(0); 
} 
+0

同样与http://stackoverflow.com/questions/3784996/why-does-left-shift-operation-invoke-undefined-behaviour-when-the-left-side-oper – MOHAMED 2013-05-07 16:30:07

+0

你可以尝试制作int声明一个unsigned int并告诉我们它是否会有所作为? – 2014-01-07 19:54:14

回答

4

在C中,与(你的情况int)尺寸比型尺寸更大的移位是未定义的行为

从这topic:从ISO C99相关报价(6.5.7/4)

E1的结果< < E2是E1左移E2位的位置;腾空的比特用零填充。如果E1具有无符号类型,则结果的值是E1×2 E2,减模 比结果类型中可表示的最大值多一个。如果E1有一个有符号的 类型和非负值,并且E1×2 E2可以表示结果类型,那么就是 的结果值;否则,行为未定义

+0

您的意思是,如果移动距离与字体大小相同,它仍然是未定义的? – zhengbli 2013-05-07 16:25:48

+0

哦,现在我明白了。谢谢! – zhengbli 2013-05-07 16:28:00

+0

是的。如果你的字体大小为32,那么你可以使用数字<= 31 – MOHAMED 2013-05-07 16:28:06

2

假设你有32位整数,左移位超过31倍的结果是不确定的

从C11 §6.5.7 Bitwise shift operators

E1 < < E2的结果E1左移E2位位置;腾空的 位填充了零。如果E1具有无符号类型,则值为 ,结果为E1 x 2E2,比结果类型中可表示的最大值 的模数减1。如果E1具有带符号的类型和非负值,并且E1 x 2E2可在结果类型中表示,则 即为结果值;否则,行为是未定义的 。

+0

哦,这个解释清楚。感谢您的参考! – zhengbli 2013-05-07 16:26:46