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

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

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

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

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


当前回答

我只是想强调斯利姆的观点。转换构造创建了一个完整的、一等公民的范围。因此,可以在switch语句中在第一个case标签之前声明(并初始化)一个变量,而不需要额外的括号对:

switch (val) {  
  /* This *will* work, even in C89 */
  int newVal = 42;  
case VAL:
  newVal = 1984; 
  break;
case ANOTHER_VAL:  
  newVal = 2001;
  break;
}

其他回答

整个switch语句在同一个作用域中。要解决这个问题,可以这样做:

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

    case ANOTHER_VAL:
      ...
    break;
}

注意括号。

试试这个:

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

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

有趣的是,这很好:

switch (i)  
{  
case 0:  
    int j;  
    j = 7;  
    break;  

case 1:  
    break;
}

... 但这不是:

switch (i)  
{  
case 0:  
    int j = 7;  
    break;  

case 1:  
    break;
}

我得到一个修复足够简单,但我不明白为什么第一个例子不打扰编译器。正如之前所提到的(2年前的呵呵),声明不是导致错误的原因,即使有逻辑。初始化是问题所在。如果变量在不同的行上被初始化和声明,它将被编译。

如果你开始一个新块,你可以在switch语句中声明变量:

switch (thing)
{ 
  case A:
  {
    int i = 0;  // Completely legal
  }
  break;
}

原因是与在堆栈上分配(和回收)空间以存储局部变量有关。