当`default:`标签放在大括号外时,复合开关语句中的局部变量是否被初始化?

Joh*_*zem 6 c language-lawyer

通常在使用switch语句时,您无法定义初始化复合语句的局部变量,例如

switch (a)
{
  int b = 5;  /* Initialization is skipped, no matter what a is */

  case 1:
    /* Do something */
    break;
  default:
   /* Do something */
   break;
}
Run Code Online (Sandbox Code Playgroud)

但是,由于该switch语句是一个类似foror 的语句while,因此没有反对不使用复合语句的规则,请查看此处的示例.但这意味着,可以在switch关键字和左括号之后的右括号之间使用标签.

所以在我看来,有可能并且允许使用这样的switch语句:

switch (a)
  default:
{
  int b = 5;  /* Is the initialization skipped when a != 1? */
    /* Do something for the default case using 'b' */
    break;

  case 1: // if a == 1, then the initialization of b is skipped.
    /* Do something */
    break;
}
Run Code Online (Sandbox Code Playgroud)

我的问题:在这种情况下是否必须执行初始化(a!= 1)?根据我所知的标准,是的,它应该是,但我无法直接在我提供的任何文件中找到它.任何人都可以提供确定的答案吗?

在我得到这方面的评论之前,是的,我知道这不是在现实世界中编程的方法.但是,和往常一样,我对语言规范的界限感兴趣.我从来没有容忍这种风格我的编程团队!

rod*_*igo 7

大多数人认为a switch如果是多,但从技术上来说它是计算的goto.而case <cte>:default:实际上的标签.所以goto适用于这些情况的规则.

你既您的例子是语法上合法的,但在第二个,当a==1b初始化将被跳过,它的价值是不确定的.没有问题,只要你不使用它.

参考:

根据C99标准6.2.4.5,关于自动变量:

如果为对象指定了初始化,则每次在执行块时达到声明时都会执行初始化;

因此,每次执行流程到达初始化时,变量都会被初始化,就像它是一个赋值一样.如果你第一次跳过初始化,那么变量将保持未初始化状态.