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语句本质上是一个计算的gotocase 标签可以出现在由 switch 控制的(通常是复合的)语句中的任何位置,甚至在嵌套块中也是如此。

声明 int bla = 255; 创建了一个 int 对象 bla ,其生命周期是封闭块的执行,其名称从其声明点到结束都是可见的块。

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

你可以用 goto 语句做同样的事情

不要那样做。

(对于 gcc,如果您使用 -Wall-Wextra-Wmaybe-uninitialized 进行编译,您将收到警告。)

(关于 switch 语句的另一种滥用,请参见 Duff's Device。)