我一直在想这个问题——为什么不能在switch语句的case标签后面声明变量呢?在c++中,你可以在任何地方声明变量(并且在第一次使用时声明它们显然是一件好事),但以下仍然不能工作:

switch (val)  
{  
case VAL:  
  // This won't work
  int newVal = 42;  
  break;
case ANOTHER_VAL:  
  ...
  break;
}  

上面给了我以下错误(MSC):

'newVal'的初始化被'case'标签跳过

这在其他语言中似乎也是一个限制。为什么这是一个问题?


当前回答

我最喜欢的邪恶切换技巧是使用if(0)跳过不需要的case标签。

switch(val)
{
case 0:
// Do something
if (0) {
case 1:
// Do something else
}
case 2:
// Do something in all cases
}

但非常邪恶。

其他回答

交换机的整个部分是一个单独的声明上下文。你不能像那样在case语句中声明变量。试试这个吧:

switch (val)  
{  
case VAL:
{
  // This will work
  int newVal = 42;
  break;
}
case ANOTHER_VAL:  
  ...
  break;
}

我相信手头的问题是,这是声明被跳过,你试图在其他地方使用var,它不会被声明。

试试这个:

switch (val)
{
    case VAL:
    {
        int newVal = 42;
    }
    break;
}

考虑:

switch(val)
{
case VAL:
   int newVal = 42;
default:
   int newVal = 23;
}

在没有break语句的情况下,有时newVal会声明两次,直到运行时才知道它是否声明了。我的猜测是,这种限制是由于这种混乱。newVal的范围是什么?惯例规定它将是整个开关块(在大括号之间)。

我不是c++程序员,但在C中:

switch(val) {
    int x;
    case VAL:
        x=1;
}

工作很好。在开关块中声明变量是可以的。在案件警卫之后宣布不是。

这个问题最初同时被标记为c和c++。原始代码在C和c++中都是无效的,但原因完全不同,互不相关。

In C++ this code is invalid because the case ANOTHER_VAL: label jumps into the scope of variable newVal bypassing its initialization. Jumps that bypass initialization of automatic objects are illegal in C++. This side of the issue is correctly addressed by most answers. However, in C language bypassing variable initialization is not an error. Jumping into the scope of a variable over its initialization is legal in C. It simply means that the variable is left uninitialized. The original code does not compile in C for a completely different reason. Label case VAL: in the original code is attached to the declaration of variable newVal. In C language declarations are not statements. They cannot be labeled. And this is what causes the error when this code is interpreted as C code. switch (val) { case VAL: /* <- C error is here */ int newVal = 42; break; case ANOTHER_VAL: /* <- C++ error is here */ ... break; } Adding an extra {} block fixes both C++ and C problems, even though these problems happen to be very different. On the C++ side it restricts the scope of newVal, making sure that case ANOTHER_VAL: no longer jumps into that scope, which eliminates the C++ issue. On the C side that extra {} introduces a compound statement, thus making the case VAL: label to apply to a statement, which eliminates the C issue. In C case the problem can be easily solved without the {}. Just add an empty statement after the case VAL: label and the code will become valid switch (val) { case VAL:; /* Now it works in C! */ int newVal = 42; break; case ANOTHER_VAL: ... break; } Note that even though it is now valid from C point of view, it remains invalid from C++ point of view. Symmetrically, in C++ case the the problem can be easily solved without the {}. Just remove the initializer from variable declaration and the code will become valid switch (val) { case VAL: int newVal; newVal = 42; break; case ANOTHER_VAL: /* Now it works in C++! */ ... break; } Note that even though it is now valid from C++ point of view, it remains invalid from C point of view.

从C23开始,C语言中的所有标签都将被解释为标签隐含的空语句(N2508),也就是说,在C语言中不能将标签放在声明前面的问题将不再存在,并且不再需要上述基于;的修复。