考虑以下代码:
void foo()
{
goto bar;
int x = 0;
bar: ;
}
GCC和Clang 拒绝了它,因为跳转到bar:
绕过了变量初始化。MSVC一点也不抱怨(使用x
after bar:
会引起警告)。
我们可以使用来做类似的事情switch
:
void foo()
{
switch (0)
{
int x = 0;
case 0: ;
}
}
现在所有三个编译器 发出错误。
这些代码片段格式不正确吗?还是引起UB?
我曾经以为两者都是不正确的形式,但是我找不到标准的启示部分。[stmt.goto]不说这事,而且也不[stmt.select] 。
不是标准,但是在这里可以找到一些信息:en.cppreference.com/w/cpp/language/goto 特别是:“如果控制权转移进入任何自动变量的范围(例如,通过跳过声明)语句),则程序的
—
格式
将
—
胡桃
/permissive-
标志添加到MSVC,它也会抱怨。我不知道没有该标志的MSVC的行为是否定义明确(我会这样假设,否则为什么他们会允许它?)。
@walnut “否则他们为什么会允许它”可能是为了向后兼容,或者是因为他们不太在乎标准。在默认设置下,所有主要的编译器均不符合标准。
—
HolyBlackCat
x
在跳后使用,问题将变得更加琐碎。