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

时间:2011-02-27 21:59:36

标签: c++ function switch-statement

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

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
}

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

2 个答案:

答案 0 :(得分:71)

C ++标准第6.6.4节:

  

无条件的goto声明   将控制转移到声明   由标识符标记。该   标识符应为标签(6.1)   位于当前的功能中。

C ++标准第6.7节:

  

可以转入   阻止,但不是绕过的方式   初始化声明。一个   从一个点跳过的程序   其中局部变量具有自动变量   存储持续时间不在范围内   它在范围内的点是   除非变量具有POD,否则形成不良   类型(3.9)并声明没有   初始化

强调由我添加。由于switch伪装成goto,因此您遇到此行为。要解决此问题,请在必须使用switch

时添加大括号
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 {
    ...
}

虽然对于我来说,在windows内创建vector switch您希望实现的目标并不明显,但您可能需要重新考虑您的设计。 注意我向const添加了windows限定符,因为它未在您的示例中修改过。

答案 1 :(得分:11)

交换机本质上是goto,也就是说,它是相应标签的goto。 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
    }