我正在我大学拥有的CentOS linux机器上开发一个简单的C应用程序,我与<<
运算符的行为非常奇怪。
基本上我试图根据基于变量0xffffffff
的变量shiftNum
向左移n
int shiftNum = (32 + (~n + 1));
int shiftedBits = (0xffffffff << shiftNum);
这样可以将0xffffffff
左32-n
次移位并按预期工作。但是当n = 0
和shiftNum = 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
。
有没有人知道最新情况?
答案 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按位移位运算符:
如果右操作数的值为负或者是 大于或等于提升的左操作数的宽度,行为是未定义的。
因此,结果是正确的 - 即使每次运行代码或重新编译程序或其他任何内容时都得到不同的答案。