调用函数时切换“控制权转移绕过初始化:”

switch "transfer of control bypasses initialization of:" when calling a function

提问人:Lumpi 提问时间:2/28/2011 最后编辑:user0118999881999119725 3Lumpi 更新时间:10/11/2012 访问量:122315

问:

当我尝试构建以下开关时,我收到“控制权转移绕过初始化:”错误:

switch (retrycancel)
{
    case 4:    //The user pressed RETRY
        //Enumerate all visible windows and store handle and caption in "windows"
        std::vector<MainHandles::window_data> windows = MainHandles().enum_windows().get_results(); 
        break;

    case 2: 
        //code
}

这与我调用枚举函数有关。如果不允许从交换机内调用函数,是否有解决方法解决此类问题?

C++ 函数 switch-statement

评论


答:

127赞 Sam Miller 2/28/2011 #1

C++标准的第 6.6.4 节:

无条件的 goto 语句 将控制权转移到语句 按标识符标记。这 标识符应为标签 (6.1) 位于当前函数中。

C++ 标准的第 6.7 节:

可以转移到 阻止,但不是以绕过的方式 带有初始化的声明。一个 从一个点跳出的程序 其中,具有 automatic 的局部变量 存储持续时间不在 它在范围内的点是 格式不正确,除非变量具有 POD 类型 (3.9),声明时不带 初始 化

强调是我添加的。由于真的是伪装的,所以你遇到了这种行为。要解决此问题,如果必须使用switchgotoswitch

switch (retrycancel)
    {
    case 4:
    {
        const std::vector<MainHandles::window_data> windows(
            MainHandles().enum_windows().get_results()
        );
        break;
    }
    case 2: 
        //code
    }

或重构为if/else

if (retrycancel == 4) {
    const std::vector<MainHandles::window_data> windows(
        MainHandles().enum_windows().get_results()
    );
} else if (retrycancel == 2)
    // code
} else {
    ...
}

虽然对我来说你希望通过创建内部实现什么并不明显,所以你可能需要重新考虑你的设计。注意我添加了一个限定符,因为它在您的示例中未被修改。windowsvectorswitchconstwindows

评论

1赞 Lumpi 3/1/2011
谢谢你的回答,昨天有点晚了,所以我把错误的函数调用复制到开关中,“真实”的更有意义;-)。尽管如此,我还是会使用建议的else if循环。您引用的 c++ 标准的官方来源是什么?
1赞 Sam Miller 3/1/2011
@Lumpi ISO C++ 标准,我前段时间购买了一份。
2赞 tanz 1/6/2015
@SamMiller : 您能否用更简单的术语解释为什么在某些开关情况下需要大括号。我在其中一个开关案例中创建了一个新对象,但是如果我声明或初始化一个普通变量,比如 int,我就会遇到编译器错误。我没有收到任何错误。
0赞 rxantos 5/22/2017
从技术上讲,如果和否则也是伪装的goto。或者,对于那个母体,所有的控制语句都是伪装的goto(因为它们在汇编中转向jmp)。但是,由于您使用的是大括号,因此在大小写语句周围放置大括号的效果相同。
18赞 Armen Tsirunyan 2/28/2011 #2

开关本质上是 ,也就是说,它是相应标签的 a。C++ 标准禁止 goto 绕过非 POD 对象的初始化。将向量声明放入大括号中,它将解决问题gotogoto

switch (retrycancel)
    {
     case 4:                //The user pressed RETRY
     {
        std::vector<MainHandles::window_data> windows = MainHandles().enum_windows().get_results(); //Enumerate all visible windows and store handle and caption in "windows"
        break;
     }
    case 2: 
        //code
    }

评论

0赞 Lumpi 3/1/2011
谢谢!正如你提到的,这是一个goto,当我试图学习一些正确的编程时,我想我会选择Sam Miller建议的if else if块。