问题描述
goto error;
if (false)
{
error:
cout << "error block" << endl;
}
else
{
cout << "else block" << endl;
}
当我运行此代码时,仅显示 error block
,如预期(我猜?)。但这是所有编译器都定义的行为吗?
解决方法
是的,这是很好的定义。来自stmt.goto#1
goto 语句无条件地将控制转移到由标识符标记的语句。 标识符应是位于当前函数中的标签。
有一些限制,例如案例标签不能跨越非平凡的初始化
goto error;
int i = 42;
error: // error: crosses initialization of i
但是这些不适用于您的示例。此外,在跨越初始化的情况下,这是一个硬编译器错误,因此您不必担心未定义的行为。
请注意,一旦您跳转到案例标签 error
,您实际上就处于 if
条件的真实分支内,并且通过 {{1 }}。因此,您可以保证不会执行 goto
分支。
我的 5 美分:
如果你的编译器有优化器,代码会以如下方式减少:
// more code here
goto error; // this go directly to the label
if (false)
{
error:
cout << "error block" << endl;
// this skips else clause
}
else
{
cout << "else block" << endl;
}
// more code here
所以编译后的代码就变成这样了:
// more code here
{
cout << "error block" << endl;
}
// more code here
这是Godbolt的链接:
https://gcc.godbolt.org/z/nY6E166Pz
(我确实简化了一些代码,以便汇编更易于阅读)