在switch语句中第一个’case’之前的代码
在C中,可以在第一个case
标签之前编写代码。 有没有这样做的情况,或者它只是一个“死代码块”?
例如:
switch (...) { { int a = 0x2a; printf("%d\n", a); } case 0: ... }
声明范围仅限于switch
块的变量可能很有用(但请注意,将跳过这些变量的任何初始化器):
switch (...) { int n; case 0: ... }
理论上,您也可以将代码放在那里使用goto
。
我认为这不是一个特征,而是一个关于C如何处理switch
/ case
的工件 – 只是一系列跳转目标而不受语法限制。 这就是为什么Duff的设备可以工作,这也是为什么第一个case
之前的代码不会运行的原因。
如果您查看生成的程序集,您将看到代码将被跳过:
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
C标准文档有一个示例,可以准确解释此类构造的行为(6.8.4.2/7“switch语句”):
示例在人工程序片段中
switch (expr) { int i = 4; f(i); case 0: i = 17; /* falls through into default code */ default: printf("%d\n", i); }
标识符为
i
的对象存在自动存储持续时间(在块内)但从未初始化,因此如果控制表达式具有非零值,则对printf
函数的调用将访问不确定的值。 同样,无法访问函数f
的调用。
因此,尽管这是允许的,但很容易就是“只是因为你不能意味着你应该”的情况之一。 该构造令人困惑,并且很容易导致使用未初始化的变量,因为可能很难清楚初始化是否发生以及发生在何处。
我不明白你的追求。 为什么不把代码放在案例之前呢?
int a = 0x2a; printf("%d\n", a); switch (...) { case 0: ... }
这不是你想要的吗? (除了在您的示例中,如果编译器没有抱怨,代码将永远不会运行。)