在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: ... } 

这不是你想要的吗? (除了在您的示例中,如果编译器没有抱怨,代码将永远不会运行。)