Is jumping over a variable initialization ill-form

2020-08-10 04:29发布

Consider this code:

void foo()
{
    goto bar;
    int x = 0;
    bar: ;
}

GCC and Clang reject it, because the jump to bar: bypasses variable initialization. MSVC doesn't complain at all (except using x after bar: causes a warning).

We can do a similar thing with a switch:

void foo()
{
    switch (0)
    {
        int x = 0;
        case 0: ;
    }
}

Now all three compilers emit errors.

Are those snippets ill-formed? Or do they cause UB?

I used to think that both were ill-formed, but I can't find the revelant parts of the standard. [stmt.goto] doesn't say anything about this, and neither does [stmt.select].

2条回答
Juvenile、少年°
2楼-- · 2020-08-10 04:45

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.

查看更多
forever°为你锁心
3楼-- · 2020-08-10 05:07

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

  1. scalar types declared without initializers
  2. class types with trivial default constructors and trivial destructors declared without initializers
  3. cv-qualified versions of one of the above
  4. arrays of one of the above
查看更多
登录 后发表回答