为什么不能在switch语句中声明变量?

时间:2009-01-16 07:11:25

标签: c++ c

我想了解更多关于“Why can’t variables be declared in a switch statement?

的信息

我看过这篇文章,但我并没有完全理解。 您可以在switch内部声明变量,但是要decalre并初始化变量或声明类的对象,它会给出complie time error。

请解释我......

2 个答案:

答案 0 :(得分:20)

基本上是因为如果没有命中包含变量初始化的标签,则会跳过变量的初始化。这将是不好的,因为当且仅当初始化代码已经运行时,编译器才必须发出会破坏所述变量的代码。

例如:

class A
{
  // has some non-trivial constructor and destructor
};

switch (x)
{
  case 1:
    A a;
    break;
  default:
    // do something else
}

如果代码已达到default,则a将不会被初始化。编译器必须能够提前解决这个问题。可能出于性能原因,这是不允许的。

简单的解决方法是引入一个新的范围层:

class A
{
  // has some non-trivial constructor and destructor
};

switch (x)
{
  case 1:
    {
      A a;
    }
    break;
  default:
    // do something else
}

这样就可以了,a的破坏现在定义得很好。

答案 1 :(得分:8)

语言语法和常识之间存在冲突。对于我们这些人来说,看起来这段代码(取自1800 INFORMATION的答案)应该可以正常工作:

class A
{
  // has some non-trivial constructor and destructor
};

switch (x)
{
  case 1:
    A a;
    break;
  default:
    // do something else
}

毕竟,大括号定义 a 的范围;只有当我们输入 case 1 时才会创建它,它会在离开 case 1 块后立即销毁,除非我们输入 case 1 否则它将永远不会被使用EM>。事实上, case 标签和 break 指令不会分隔范围,因此 a 之后存在于所有块中,即使它是逻辑上的不可达。当然,从语法的角度来看,没有 case 1 块这样的东西。

如果您认为switch语句是伪装的一堆(结构化) goto 指令,则范围问题会变得更加明显:

{
  if (x == 1)
    goto 1;
  else
    goto default;

  1:
    A a;
    goto end;

  default:
    // do something else

  end:
}