如果使用 goto 将控制权转移到 if(false) 块会发生什么?

问题描述

通过尝试解决一个困难的“嵌套条件”问题,我想到了以下代码

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

(我确实简化了一些代码,以便汇编更易于阅读)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...