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

时间:2012-01-06 11:09:22

标签: 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;
}

但是,由于switch语句是forwhile之类的语句,因此没有规则禁止不使用复合语句look here for examples。但这意味着,可以在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;
}

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

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

1 个答案:

答案 0 :(得分:7)

大多数人认为switch是多重的,但从技术上讲它是一个计算的gotocase <cte>:default:实际上是标签。所以goto的规则适用于这些情况。

您的两个示例在语法上都是合法的,但在第二个示例中,当a==1 b初始化将被跳过并且其值将是未定义的。没有问题,只要你不使用它。

<强>参考

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

  

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

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