在switch case语句中初始化数组

Olu*_*ide 1 c c++ arrays initialization switch-statement

奇怪的是,我c在一个switch语句中初始化了以下数组,完全期望我的编译器说不,你不能这样做,但令我惊讶的是它在MSVC,GCC和Clang编译.在线示例

我假设标准允许它,在这种情况下我的问题是为什么?...考虑到case语句中不允许声明和初始化非数组.

int main()
{
    char ch;

    switch( ch )
    {
    case 'x':
        //int a = 42; // NOT OKAY
        break;

    case 'y':
        int b;
        b = 42;    // OKAY

    case 'z':
        int c[2] = { 0 , 1 };  // OKAY (Huh???)
        break;
    };
}
Run Code Online (Sandbox Code Playgroud)

mol*_*ilo 6

如果您将示例更改为

int main()
{
    char ch;

    switch( ch )
    {
    case 'x':
        int c[2] = { 0 , 1 };
        break;

    case 'z':
        int a = 42;
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

你会注意到数组现在出现错误,但不是int.

最后一种情况实际上允许初始化.

规则不是"你不允许在一个变量中初始化变量case",但是"你不允许跳过变量初始化."

在最后一种情况下,跳过初始化是不可能的.

规则的原因是a中声明的变量在case后续情况下属于范围,跳转到后续情况会绕过初始化.

如果您重写为goto序列,这会变得(略微)更清晰,因为关于范围和初始化的相同规则适用:

if (ch == 'x') goto x;
if (ch == 'y') goto y;
if (ch == 'z') goto z;
goto end;
{
  x:
    int a = 42;  // goto y or z breaks this
    goto end;
  y:
    int b;      // uninitialised, so OK
    b = 42;
    goto end;
  z:
    int c[2] = {0, 1};  // No label after this, so can't jump across, so OK
    goto end;
}
end:
Run Code Online (Sandbox Code Playgroud)