繁体   English   中英

切换语句中第一个“ case”之前的代码

[英]Code before the first 'case' in a switch-statement

在C语言中,可以在第一个case标签之前编写代码。 是否在任何情况下对此有用,还是仅仅是“死代码”?

例如:

switch (...)    {
  {
    int a = 0x2a;
    printf("%d\n", a);
  }
  case 0:
    ...
}

我认为这不是功能,而是关于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

因此,即使允许这样做,也很容易成为“仅因为您不能代表您应该这样做”情况之一。 该构造令人困惑,并且很容易导致使用未初始化的变量,因为它尚不清楚初始化是否在何处发生。

声明范围仅限于switch块的变量可能很有用(但请注意,这些变量的所有初始化程序都将被跳过):

switch (...)
{
    int n;

    case 0:
    ...
}

从理论上讲,您还可以将代码放入使用goto

我不明白你的后继。 为什么不将代码放在案件前面呢?

int a = 0x2a;
printf("%d\n", a);
switch (...)    {
case 0:
...
}

这与您的打算不一样吗? (除了您的示例中的代码,如果编译器没有抱怨,该代码将永远不会运行。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM