switch "transfer of control bypasses initialization of:" when calling a function
C++FunctionSwitch StatementC++ 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
}