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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5136295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:29:29  来源:igfitidea点击:

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

c++functionswitch-statement

提问by Lumpi

I get a "transfer of control bypasses initialization of:" error when i try to build the following switch:

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

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
}

It has something to do with my calling my enumerate function. If it is not allowed to call a function from within a switch, is there a workaround for this kind of problem?

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

回答by Sam Miller

section 6.6.4 of the C++ standard:

C++ 标准的第 6.6.4 节:

The goto statement unconditionally transfers control to the statement labeled by the identifier. The identifier shall be a label (6.1) located in the current function.

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

section 6.7 of the C++ standard:

C++ 标准的第 6.7 节:

It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer

可以转移到一个块中,但不能绕过带有初始化的声明。从具有自动存储持续时间的局部变量不在范围内的点跳转到它在范围内的点的程序是格式错误的,除非该变量具有 POD 类型 (3.9) 并且在没有初始化程序的情况下声明

Emphasisadded by me. Since switchis really gotoin disguise, you're encountering this behavior. To solve this, add braces if you must use a switch

重点是我加的。既然switchgoto伪装,你就会遇到这种行为。要解决这个问题,如果必须使用switch

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

or refactor into if/else

或重构为if/else

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

Though it's not obvious to me what you're hoping to accomplish with creating the windowsvectorinside a switch, so you may want to rethink your design. NoteI added a constqualifier to windowssince it's not modified in your example.

虽然我不清楚您希望通过创建windowsvector内部 a来完成什么switch,因此您可能需要重新考虑您的设计。注意我添加了一个const限定符 towindows因为它在你的例子中没有被修改。

回答by Armen Tsirunyan

a switch is essentially a goto, that is, it is a gototo the appropriate label. The C++ standard forbids a goto to bypass an initialization of a non-POD object. Take the vector declaration into braces and it will solve the problem

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

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
    }