【问题标题】:Does computed `goto` respect C++ object lifetime?计算的“goto”是否尊重 C++ 对象的生命周期?
【发布时间】:2020-03-23 11:40:50
【问题描述】:

C++ 中的常规 goto 尊重对象生命周期 - 即使用 goto 跳出块将运行适当局部变量的析构函数。

start:
NonTrivial object;
if (again()) goto start;  // will call object.~NonTrivial()

使用Labels as Values 扩展时也是如此吗?

start:
NonTrivial object;
goto *(again() ? &&start : &&end);
end:

GCC 很乐意接受此代码,但似乎忽略了goto 可能对object 的生命周期产生的任何影响。 Clang 抱怨:

error: cannot jump from this indirect goto statement to one of its possible targets
note: possible target of indirect goto statement
note: jump exits scope of variable with non-trivial destructor   

Compiler Explorer 中查找对NonTrivial()~NonTrivial() 的调用。

哪个编译器行为正确?一般来说,是否有可能支持这种间接分支并正确管理对象生命周期和 RAII?

【问题讨论】:

  • 在使用扩展时“哪个编译器行为正确”是一个没有实际意义的问题。有什么权威可以回答这个问题?
  • 你不应该使用goto: xkcd.com/292
  • @Superlokkus:是的,这是反对 goto 的有根据的论据。
  • “一般来说,是否有可能支持这种间接分支并正确管理对象生存期和 RAII”。有可能,但总的来说,这需要编译器编写者付出很大的努力,所以将来不太可能发生(处理某些情况很容易,但一般情况很难,需要代码自省) .
  • @Superlokkus 应该是“你不应该使用goto 不小心”。

标签: c++ gcc goto raii


【解决方案1】:

哪个编译器行为正确?

由于我们讨论的是 GCC 的语言扩展,我们不能使用 C++ 标准来判断。但是可以合理地期望编译器会自动调用这里的析构函数与构造函数相同的次数,或者拒绝编译为 Clang。

一般来说,是否有可能支持这种间接分支并正确管理对象生命周期和 RAII?

可能是的,因为 GCC 错误已报告但尚未关闭:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37722

【讨论】:

    猜你喜欢
    • 2013-06-11
    • 1970-01-01
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 2011-03-16
    • 1970-01-01
    • 2014-11-20
    相关资源
    最近更新 更多