考虑这个C代码,其中foo
是int
:
switch(foo){
case 1: {
int bla = 255;
case 2:
printf("case12 %d\n", bla);
break;
case 3:
printf("case3 %d\n", bla);
}
};
对于foo
的不同值,代码提供以下输出:
case12 255 # foo=1
case12 255 # foo=2
case3 0 # foo=3
我在理解foo=3
时遇到了问题。声明bla
并定义其值的行不应在foo=3
时执行。 switch语句应该直接跳转到case 3:
的标签。然而,没有任何警告,所以bla
似乎至少已被宣布。它可能是未初始化的,它的值恰好是0
。你能解释一下,"案例3"中发生了什么,以及为什么这是合法的C代码?
答案 0 :(得分: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's Device。)