跳过变量初始化格式错误还是会导致未定义的行为?

Hol*_*Cat 17 c++ goto initializer variable-declaration language-lawyer

考虑这个代码:

void foo()
{
    goto bar;
    int x = 0;
    bar: ;
}
Run Code Online (Sandbox Code Playgroud)

GCC 和 Clang拒绝它,因为跳转到bar:绕过变量初始化。MSVC 根本不抱怨(除非使用xafterbar:导致警告)。

我们可以用 a 做类似的事情switch

void foo()
{
    switch (0)
    {
        int x = 0;
        case 0: ;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在所有三个编译器都发出错误

这些片段格式不正确吗?或者他们会导致UB?

我曾经认为两者都是格式错误的,但我找不到标准的相关部分。[stmt.goto]不说这事,而且也不[stmt.select]

Sto*_*ica 20

当初始化为非空时,它的格式不正确。

[stmt.dcl]

3可以转移到块中,但不能通过初始化绕过声明(包括条件和初始化语句中的声明)。一个程序从具有自动存储持续时间的变量不在范围内的点跳转到它在范围内的点是格式错误的,除非该变量具有空初始化([basic.life])。在这种情况下,具有空初始化的变量按其声明的顺序构造。

初始化程序使初始化非空。相比之下,这

void foo()
{
    goto bar;
    int x; // no initializer
    bar: ;
}
Run Code Online (Sandbox Code Playgroud)

将是良好的。尽管使用x不确定值的通常警告将适用。

  • @Cruncher - C89 需要它。C++ 从来没有这样做过,现代 C 也不再这样做了。 (4认同)