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

C++FunctionSwitch Statement

C++ Problem Overview


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?

C++ Solutions


Solution 1 - C++

section 6.6.4 of the C++ standard:

> 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.

section 6.7 of the C++ standard:

> 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

Emphasis added by me. Since switch is really goto in disguise, you're encountering this behavior. To solve this, add braces if you must use a 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 (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 windows vector inside a switch, so you may want to rethink your design. Note I added a const qualifier to windows since it's not modified in your example.

Solution 2 - C++

a switch is essentially a goto, that is, it is a goto to 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 (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
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLumpiView Question on Stackoverflow
Solution 1 - C++Sam MillerView Answer on Stackoverflow
Solution 2 - C++Armen TsirunyanView Answer on Stackoverflow