来自的抽象操作语义ISO/IEC 9899
说:
6.5.7 Bitwise shift operators --- Semantics
3 ………… 如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义。
在您的情况下,拆卸并查看会发生什么,我们会看到:
[root@arch stub]# objdump -d a.out | sed '/ <main>/,/^$/ !d'
00000000004004f6 <main>:
4004f6: 55 push %rbp
4004f7: 48 89 e5 mov %rsp,%rbp
4004fa: 48 83 ec 10 sub $0x10,%rsp
4004fe: c7 45 fc 07 00 00 00 movl $0x7,-0x4(%rbp)
400505: b8 20 00 00 00 mov $0x20,%eax
40050a: 89 c1 mov %eax,%ecx
40050c: d3 65 fc shll %cl,-0x4(%rbp) <<== HERE IS THE PROBLEM
40050f: 8b 45 fc mov -0x4(%rbp),%eax
400512: 89 c6 mov %eax,%esi
400514: bf b4 05 40 00 mov $0x4005b4,%edi
400519: b8 00 00 00 00 mov $0x0,%eax
40051e: e8 cd fe ff ff callq 4003f0 <printf@plt>
400523: b8 00 00 00 00 mov $0x0,%eax
400528: c9 leaveq
400529: c3 retq
40052a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
生成的代码确实尝试移动,但shll %cl,-0x4(%rbp)
(长的左移)没有效果。
在undefined behaviour
这种情况下,在于组装,即在 SHL 操作中。