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

我想更多地了解“ 为什么不能在switch语句中声明变量? ”

我读了这篇文章,但我并没有完全理解。 你可以在switch内部声明变量,但是要decalre并初始化一个变量,或者声明class的对象,它会给出complie time error。

请解释一下……

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

例如:

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的破坏。

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

 class A { // has some non-trivial constructor and destructor }; switch (x) { case 1: A a; break; default: // do something else } 

毕竟,花括号定义了a的范围; 它只在我们输入案例1时才被创建,它在离开案例1块后立即被销毁,除非我们进入案例1,否则它将永远不会被使用。 实际上, case标签和break指令不会分隔范围,因此即使它在逻辑上无法访问,也会在之后的所有块中存在。 当然,从语法的角度来看,没有案例1块。

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

 { if (x == 1) goto 1; else goto default; 1: A a; goto end; default: // do something else end: }