【发布时间】: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不小心”。