代码之家  ›  专栏  ›  技术社区  ›  tur1ng

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

  •  15
  • tur1ng  · 技术社区  · 15 年前

    在C语言中,可以在第一个 case 标签。有没有什么情况下这样做是有用的,或者它只是一个“死代码块”?

    例如。:

    switch (...)    {
      {
        int a = 0x2a;
        printf("%d\n", a);
      }
      case 0:
        ...
    }
    
    4 回复  |  直到 9 年前
        1
  •  11
  •   caf    15 年前

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

    switch (...)
    {
        int n;
    
        case 0:
        ...
    }
    

    从理论上讲,你也可以把你要使用的代码放在那里。 goto .

        2
  •  18
  •   Joey Gumbo    15 年前

    我认为这与其说是一个特征,不如说是一个C如何处理的人工制品。 switch / case _“,作为一系列不受语法限制的跳转目标。这就是为什么 Duff's device 这也是为什么代码在第一个 案例 永远不会跑。

    如果查看生成的程序集,您将看到代码将被跳过:

        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
    
        3
  •  12
  •   Michael Burr    15 年前

    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 无法联系。

    因此,尽管这是允许的,但很容易出现“仅仅因为你不能意味着你应该”的情况。构造容易混淆,并且很容易导致使用未初始化的变量,因为它可能非常不清楚初始化是否发生以及在何处发生。

        4
  •  1
  •   AnthonyLambert    15 年前

    我不明白你想干什么。为什么不把代码放在案例前面呢?

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

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