switch 语句中的声明
Declarations in switch statement
考虑这个 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
。当 foo=3
时,声明 bla
并定义其值的行不应执行。 switch 语句应该直接跳转到 case 3:
的标签。但是没有警告,所以 bla
似乎至少已经声明了。它可能会在未初始化的情况下使用,但它的值恰好是 0
。您能解释一下 "case 3" 中发生了什么吗?为什么这是合法的 C 代码?
一个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。)
考虑这个 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
。当 foo=3
时,声明 bla
并定义其值的行不应执行。 switch 语句应该直接跳转到 case 3:
的标签。但是没有警告,所以 bla
似乎至少已经声明了。它可能会在未初始化的情况下使用,但它的值恰好是 0
。您能解释一下 "case 3" 中发生了什么吗?为什么这是合法的 C 代码?
一个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。)