Is jumping over a variable initialization ill-formed or does it cause undefined behaviour?
It's ill-formed when the initialization is non-vacuous.
[stmt.dcl]
3 It is possible to transfer into a block, but not in a way that bypasses declarations with initialization (including ones in conditions and init-statements). A program that jumps from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has vacuous initialization ([basic.life]). In such a case, the variables with vacuous initialization are constructed in the order of their declaration.
The initializer makes the initialization non-vacuous. To contrast, this
void foo()
{
goto bar;
int x; // no initializer
bar: ;
}
would be well-formed. Though the usual caveats about using x
with an indeterminate value would apply.
From goto statement:
If transfer of control enters the scope of any automatic variables (e.g. by jumping forward over a declaration statement), the program is ill-formed (cannot be compiled), unless all variables whose scope is entered have
- scalar types declared without initializers
- class types with trivial default constructors and trivial destructors declared without initializers
- cv-qualified versions of one of the above
- arrays of one of the above