switch语句中的声明

con*_*use 4 c declaration switch-statement

考虑这个C代码,其中fooint:

switch(foo){
    case 1: {
        int bla = 255;
        case 2:
            printf("case12 %d\n", bla);
        break;
        case 3:
            printf("case3  %d\n", bla);
    }
};
Run Code Online (Sandbox Code Playgroud)

对于不同foo的代码值,给出以下输出:

case12 255   # foo=1
case12 255   # foo=2
case3  0     # foo=3
Run Code Online (Sandbox Code Playgroud)

我有一个问题的理解foo=3.声明bla和定义其值的行不应该在何时执行foo=3.switch语句应该直接跳转到标签case 3:.然而,没有警告,所以bla似乎至少已经宣布.它可能是未初始化的,但它的价值恰好是0.你能解释一下,"案例3"中发生了什么,以及为什么这是合法的C代码?

Kei*_*son 7

一个switch语句本质上是一个计算goto.该case标签可以由受控的(通常为化合物)语句内的任何地方出现switch,即使在嵌套块.

该声明int bla = 255;创建一个int对象,bla其生命周期是封闭块的执行,其名称从其声明点到块的末尾是可见的.

如果switch语句会导致控制跳到case 2:case 3:标签,它一跃而起的范围bla,但跳过去的初始化.然后值bla是垃圾(不是随机的,不一定0),实际上试图引用它的值有未定义的行为.

你可以用goto声明做同样的事情

不要那样做.

(对于gcc,如果用-Wall,或-Wextra,或者编译,你会收到警告-Wmaybe-uninitialized.)

(对于另一个滥用switch声明,请参阅Duff的设备.)

  • @ con-f-use:它存在,因为控件进入了定义它的块.它的*生命周期*在控制到达(或跳过)开头`{`时开始,并在控制到达结束时}结束.在控制到达声明之前不会发生初始化 - 如果声明被跳过,则根本不会发生.(C++禁止这种跳跃.) (2认同)