为什么禁止在 constexpr 函数中使用 goto?

Why disallow goto in constexpr functions?

C++14 对在 constexpr 函数中可以做什么和不能做什么有规定。其中一些(没有 asm,没有静态变量)看起来很合理。但是标准也不允许在 constexpr 函数中使用 goto,即使它允许其他控制流机制。
这种区别背后的原因是什么?
我以为我们已经过去了“goto 对编译器来说很难”。

我的理解是希望在 C++14 中放宽 constexpr 语义。许多放宽的限制都很简单,但有些限制更具争议性或难度或 [在此处插入您选择的形容词]。与其仅仅为了使用 goto 的能力而放松 constexpr,而是决定只发布主要更改并推迟其余部分。这似乎是一个非常合理的选择,因为 C++14 中的 constexpr 比 C++11 中的 constexpr 强大得多,并且不能使用 goto 是一个相当小的问题缺席,综合考虑。

也就是说,肯定存在这样一种观点,即在 constexpr 上下文中使用 goto 既有用又可能。事实上,initial proposal for relaxing constexpr allowed it. So maybe all it takes is somebody that wants it to write a proposal to add it. That somebody could be you! was apparently Ville Voutilainen two years ago in N4472,其中包含与此问题相当相关的段落:

There is unsubstantiated hearsay according to which banning goto in constant expressions is more for taste reasons than technical reasons, meaning that supporting goto in constant expressions isn't particularly hard to implement. I can't say whether that's correct for implementations in general.

这篇论文的接受度不一,但现在我们有了 constexpr lambda,也许需要重新审视它。 那个某人可能就是你!

constexpr 预计将由编译器的前端以某种伪解释模式或在生成任何可执行代码之前单次构建的抽象语法树上进行评估。我们知道 goto 可能会跳转到函数末尾尚未计算的某个部分。因此,正确连接调用和执行 goto 将强制在多个通道中构建 AST,并且在树中的节点之间跳出顺序仍然是一个可能破坏某些状态的混乱操作。所以这样的构造是不值得的。