左逻辑转换行为不一致

时间:2015-09-05 21:52:47

标签: c bitwise-operators

我正在我大学拥有的CentOS linux机器上开发一个简单的C应用程序,我与<<运算符的行为非常奇怪。

基本上我试图根据基于变量0xffffffff的变量shiftNum向左移n

int shiftNum = (32 + (~n + 1));
int shiftedBits = (0xffffffff << shiftNum);

这样可以将0xffffffff32-n次移位并按预期工作。但是当n = 0shiftNum = 32时,我会遇到一些非常奇怪的行为。我没有得到预期的0x00000000 0xffffffff

例如这个脚本:

int n = 0;
int shiftNum  = (32 + (~n + 1));
int shiftedBits = (0xffffffff << shiftNum );
printf("n: %d\n",n);
printf("shiftNum: 0x%08x\n",shiftNum);
printf("shiftedBits: 0x%08x\n",shiftedBits);
int thirtyTwo = 32;
printf("ThirtyTwo: 0x%08x\n",thirtyTwo);
printf("Test: 0x%08x\n", (0xffffffff << thirtyTwo));

输出:

n: 0
shiftNum: 0x00000020
shiftedBits: 0xffffffff
ThirtyTwo: 0x00000020
Test: 0x00000000

我不知道发生了什么。我怀疑一些疯狂的低级别的东西。更奇怪的是操作(0xffffffff << (shiftNum -1)) << 1输出0x00000000

有没有人知道最新情况?

1 个答案:

答案 0 :(得分:1)

如果调用未定义的行为,则结果未指定且任何内容都有效。

n为0时,32 + (~n + 1)为32(在二进制补码CPU上)。如果sizeof(shiftNum) == 4(或sizeof(shiftNum) * CHAR_BIT == 32,通常具有相同的结果),那么您只能按值0..31移动;其他任何事情都是未定义的行为。

  

ISO / IEC 9899:2011§6.5.7按位移位运算符:

     

如果右操作数的值为负或者是   大于或等于提升的左操作数的宽度,行为是未定义的。

因此,结果是正确的 - 即使每次运行代码或重新编译程序或其他任何内容时都得到不同的答案。