根据C标准 §6.5.7.3
,按类型大小移动是未定义的行为:
6.5.7按位移位运算符
(…)如果右操作数的值为负或大于 或等于 提升后的左操作数的宽度,则行为未定义。
您的编译器应就此警告您:
$ gcc shift.c -o shift -Wallshift.c: In function ‘main’:shift.c:5:5: warning: left shift count >= width of type [enabled by default]shift.c:6:5: warning: right shift count >= width of type [enabled by default]
如果看一下gcc生成的汇编代码,您会发现它实际上是在编译时计算前两个结果。简化:
main: movl $0, %esi call printf movl $0, %esi call printf movl -4(%rbp), %ecx ; -4(%rbp) is n movl $-1, %esi sall %cl, %esi ; This ignores all but the 5 lowest bits of %cl/%ecx call printf movl -4(%rbp), %ecx movl $-1, %esi shrl %cl, %esi call printf



