C标准中对可变修改类型的switch语句约束的说明

rea*_*esk 13 c label goto declaration switch-statement

我正在编写C编译器,当我执行该switch语句时,一个约束使我很困惑。标准的 6.8.4.2p2节规定:

如果switch语句在标识符的范围内具有关联的大小写或默认标签,且标识符的类型可变,则整个switch语句应在该标识符的范围内。

带有脚注:

也就是说,声明要么在switch语句之前,要么在最后一个case或默认标签之后,该标签与包含该声明的块中的switch关联。

我真的不明白这个约束的含义。可以给我一个例子吗?

dbu*_*ush 2

这意味着,如果一种情况能够看到可变修改的数组,那么整个switch语句也必须能够看到它。

这意味着以下代码是合法的:

void switch_test(int size)
{
    int array[size];
    ...
    // code to populate array
    ...
    switch (expr) {
    case 1:
        printf("%d\n", array[0]);
        break;
    case 2:
        // do something else
    }
}
Run Code Online (Sandbox Code Playgroud)

但这段代码不是:

void switch_test(int size)
{
    switch (expr) {
    case 2:
        // do something else
        int array[size];   // ILLEGAL, VLA in scope of one label but not all
    case 1:
        ...
        // code to populate array
        ...
        printf("%d\n", array[0]);
    }
}
Run Code Online (Sandbox Code Playgroud)

后者非法的原因是,如果代码跳转到情况 1,则array可能无法正确创建,因为 VLA 的大小是在运行时确定的。确保 VLA 在switch语句之前可见可以避免此问题。