2016-09-24 115 views
2

我在玩代码时遇到了一个有趣的特性。我正在使用Eclipse CDT 4.5.2,并启用了Cygwin和C++ 14(-std = C++ 14)。中箱的变量初始化通常是禁止的,但下面的代码编译:SWITCH语句中DEFAULT后CASE中的C++变量初始化

switch(int switchStatement = 11) 
{ 
    default: 
     ++j; 
     break; // break is optional, still compiles even if omitted 
    case 11: 
     int caseVariable = 0; 
     ++j; 
} 

如果添加另一种情况是,那么除了“跳转到case标签”被提升。

switch(int switchStatement = 11) 
{ 
    default: 
     ++j; 
    case 11: 
     int caseVariable = 0; 
     ++j; 
    case 12: // exception 
     ++j; 
} 

有人可以解释我是如何工作的吗?

+0

重新打开:dupe没有解释其中一个片段的编译成功。 (我认为这是一个编译器错误。) – Bathsheba

+0

它不工作,如果你添加一个休息到案件11? –

+0

只有当变量声明在最后一个'case'块中时它才起作用吗? –

回答

1

为什么在第二种情况下出现错误,但在最后一种情况下声明变量时没有出错?

因为C++的规则是跳转无法通过同一范围内的变量 声明。所以当你跳转到第二种情况时,你会在情况1中通过 变量声明。但是 最后一种情况下的变量声明是可以的,因为它永远不会被跳过。

规则的原因是,如果允许跳过变量 声明,那么编译器将很难确定是否调用该变量的析构函数 。如果你已经跳过了 变量声明,那么你不需要调用析构函数,如果你没有跳过,那么你会这样做。

在一个case语句中声明和初始化的变量在其他情况下仍然可见,但由于初始化代码属于另一个case,所以它们不会被初始化。

在C++问题的范围。这里,case语句是“标签”。因此,编译器会将它们视为从一个语句跳到另一个语句。在这个特定的例子中,编译器不会理解如何进一步处理。要解决此问题,您可以将案例中的代码包含到{}块中。额外的{和}表示编译器在调用析构函数时没有任何问题。因此,在声明新变量时为该特定情况声明提供范围或大括号很重要。

+0

你为什么发布你的答案两次?你可以随时编辑。 –

+0

错误,这就是为什么我删除第二篇文章 –