问题描述
考虑以下代码:
void foo()
{
goto bar;
int x = 0;
bar: ;
}
GCC和Clang 拒绝它,因为跳转到bar:
会绕过变量初始化. MSVC根本不抱怨(除非在bar:
引起警告后使用x
).
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).
我们可以使用switch
做类似的事情:
We can do a similar thing with a switch
:
void foo()
{
switch (0)
{
int x = 0;
case 0: ;
}
}
现在所有三个编译器发出错误.
这些代码片段格式不正确吗?还是会导致UB?
Are those snippets ill-formed? Or do they cause UB?
我曾经以为两者都是不正确的形式,但是我找不到该标准的启示性部分. [stmt.goto] 对此没有说什么, [stmt.select] .
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].
推荐答案
初始化非空时,它的格式不正确.
It's ill-formed when the initialization is non-vacuous.
3 可以转移到块中,但不以这种方式 绕过初始化声明(包括中的声明) 条件和初始化声明).从一个点跳下来的程序 具有自动存储期限的变量不在范围内 除非变量具有 空泡初始化([basic.life]).在这种情况下,变量 空虚初始化按其顺序构造 声明.
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: ;
}
将格式正确.尽管通常会出现关于将x
使用不确定值的警告.
would be well-formed. Though the usual caveats about using x
with an indeterminate value would apply.
这篇关于跳过变量初始化格式不正确还是会导致未定义的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!