mov ecx, DWORD PTR _x$[ebp]
mov DWORD PTR tv64[ebp], ecx
cmp DWORD PTR tv64[ebp], 0 ; here begins the switch
je SHORT $LN1@main ; jump to case 0
jmp SHORT $LN4@main ; jump out of the switch
; Line 8
mov DWORD PTR _a$752[ebp], 42
; Line 9
mov edx, DWORD PTR _a$752[ebp] ; here we have the dead code
push edx
push OFFSET $SG754
call _printf
add esp, 8
$LN1@main: ; and here case 0
; Line 12
push OFFSET $SG756
call _printf
add esp, 4
$LN4@main:
; Line 15
xor eax, eax
mov esp, ebp
pop ebp
ret 0
4条答案
按热度按时间kupeojn61#
我认为这与其说是一个特性,不如说是C如何处理
switch
/case
的一个工件--仅仅是一系列没有语法限制的跳转目标。这就是Duff's device工作的原因,也是第一个case
之前的代码永远不会运行的原因。如果查看生成的程序集,您会发现代码将被跳过:
1yjd4xko2#
C标准文档中有一个示例,它准确地解释了这种类型的构造的行为(6.8.4.2/7“开关语句”):
示例:在阿尔蒂程序片段中
标识符为
i
的对象以自动存储持续时间存在(在块内),但从未初始化,因此如果控制表达式具有非零值,则对printf
函数的调用将访问不确定值。类似地,对f
函数的调用不能到达。因此,即使这是允许的,这也很容易成为“你能并不意味着你应该”的情况之一。这种构造很容易混淆,并且很容易导致使用未初始化的变量,因为初始化是否发生以及在哪里发生是非常不清楚的。
nqwrtyyt3#
声明作用域限于
switch
块的变量可能很有用(但要注意,这些变量的任何初始化器都将被跳过):理论上,您还可以将使用
goto
获得的代码放在那里。j8yoct9x4#
我不明白你的目的。为什么不把密码放在案子之前?
这不正是您想要的吗?(除了在您的示例中,如果编译器不抱怨,代码将永远不会运行。)