"只有当初始化与声明结合时才"跨越变量的初始化"

gsi*_*011 4 c++ performance g++ switch-statement

我已经阅读了关于"跳转到案例标签"错误的这个问题,但我仍然有一些问题.我在Ubuntu 12.04上使用g ++ 4.7.

此代码给出错误:

int main() {
  int foo = 1;
  switch(foo) {
  case 1:
    int i = 0;
    i++;
    break;
  case 2:
    i++;
    break;
  }
}
Run Code Online (Sandbox Code Playgroud)

错误是

jump-to-case-label.cpp: In function ‘int main()’:
jump-to-case-label.cpp:8:8: error: jump to case label [-fpermissive]
jump-to-case-label.cpp:5:9: error:   crosses initialization of ‘int i’
Run Code Online (Sandbox Code Playgroud)

但是,这段代码很好,

int main() {
  int foo = 1;
  switch(foo) {
  case 1:
    int i;
    i = 0;
    i++;
    break;
  case 2:
    i++;
    break;
  }
}
Run Code Online (Sandbox Code Playgroud)

第二个代码是否比第一个代码更危险?我很困惑为什么g ++允许它.

其次,解决此问题的方法是确定初始化变量的范围.如果初始化变量是一个大对象,并且switch语句在while循环中,那么每次输入和离开范围时都不会调用构造函数和析构函数,从而导致效率降低?或者编译器会优化它吗?

Die*_*ühl 6

跳过对象的初始化,即使对象是类型int,也始终是未定义的行为.请注意,switch-statement的声明并不特别:它只是一个声明,人们[ab-]使用了这种有趣的方式,例如Duff的Device.声明中唯一特别的是标签可以采取形式default:case <const-integer-expr>:.

该语句int i;是变量的定义,但没有初始化.因此,不绕过变量的初始化.跳过这个定义没有比首先出现的更大的问题.当然,这个值在跳转时被分配,case 1:而不是在跳转时被分配,case 2:但这与在switch-statements 之外的代码中发生的情况没有什么不同,如果人们只定义变量.