C++ 为什么在constexpr函数中不允许goto?

C++ 为什么在constexpr函数中不允许goto?,c++,c++14,language-lawyer,constexpr,goto,C++,C++14,Language Lawyer,Constexpr,Goto,C++14有关于在constexpr函数中可以做什么和不能做什么的规则。其中一些(没有asm,没有静态变量)看起来相当合理。但是标准也不允许constexpr函数中的goto,即使它允许其他控制流机制。 这种区别背后的原因是什么? 我认为我们已经过了“goto对编译器来说很难”的阶段。我的理解是,在C++14中,有一种放松的constepr语义的愿望。许多被放松的限制都是直截了当的,但有些限制更具争议性或更难,或者[在这里插入您选择的形容词]。与其仅仅为了使用goto而搁置Releasedcon

C++14有关于在
constexpr
函数中可以做什么和不能做什么的规则。其中一些(没有
asm
,没有静态变量)看起来相当合理。但是标准也不允许
constexpr
函数中的
goto
,即使它允许其他控制流机制。
这种区别背后的原因是什么?

我认为我们已经过了“goto对编译器来说很难”的阶段。我的理解是,在C++14中,有一种放松的
constepr
语义的愿望。许多被放松的限制都是直截了当的,但有些限制更具争议性或更难,或者[在这里插入您选择的形容词]。与其仅仅为了使用goto而搁置Released
constexpr
,不如决定只发布主要更改,而搁置其余更改。这似乎是一个非常合理的选择,因为C++14中的
constexpr
比C++11中的
constexpr
功能强大得多,而且不能使用
goto
是一个相当小的缺憾,从各方面考虑

这就是说,当然存在这样一种观点,即在
constexpr
上下文中设置
goto
,既有用又可能。实际上,放松
constexpr
的方法允许这样做。所以,也许只要有人想让它写一个提案来添加它。有人可能就是你!显然,Ville Voutilainen两年前在,其特点是与此问题非常相关的一段:

有一种未经证实的传闻称,在常量表达式中禁止goto更多是出于口味原因,而不是技术原因,这意味着在常量表达式中支持goto并不特别难实现。我不能说这对于一般的实现是否正确


这份报纸受到了不同的欢迎,但现在我们有了constexpr lambdas,也许需要重新审视一下。有人可能就是你

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

即使对于编译器来说,它也是非常不可预测的。@user0042 goto仍然有它的用途,它是一个有效且必需的构造construct@user0042我不这么认为。你要破解的代码数量可能是巨大的。除此之外,
goto
确实有其罕见的用途——比如打破深层嵌套循环的多层结构。我的信念是,
goto
本身并不是一个糟糕的构造-你应该非常非常小心地使用它(通常你不应该)。@user0042:Böhm Jacopini定理告诉你,你可以随时替换goto,但代价是什么?突破深度嵌套循环或C风格错误清理的良好位置的goto通常比结构化编程解决方案更清晰。你们能继续讨论这个话题吗?这里不是讨论“goto pros&cons”的地方。这会使AST的构建复杂化吗?当然,整个翻译单元的AST将在编译器开始考虑constexpr计算之前构建。毕竟,该计算不会影响解析。@Sneftel编译器计算constexpr值的时间取决于实现(必须在前端阶段完成)但是,如果AST是一个具有明显的评估顺序和没有节点跳跃的基本单元,那么它就简单得多。C++是一种抽象语言,它的特征是否容易实现,完全不符合标准。例如,异常不容易实现,但它们在语言中。@black:“它的特性是否“容易”实现完全不在标准的考虑范围之内。”不,不是。标准委员会经常考虑实现特定功能的实现成本是否值得用户为该功能获得收益。这是旧的C++0x概念消亡的原因之一。这就是为什么C++98
导出失败的原因。@Nicolas Bolas之所以失败,是因为MS基于传闻和荒谬的说法反对导出。当然,但在某个时候,有人不得不说“好吧,循环是好的,但是一般的
转到
”有问题。为什么会出现治疗分歧?是什么让
goto
变得更具争议、更难或[其他形容词]?@T.C.谢谢!你可能认为我会发现这篇论文的字面意思是“constexpr goto”…@Barry C++11 constexpr遵循函数调用的宏式扩展。如果展开表达式为,则它们是常量表达式。在允许变异和循环的同时禁止goto并没有这样的逻辑,这显然至少同样难以实现。这是政治上的正确性,句号。@curiousguy,你打算写一篇文章,建议康斯特普·后藤吗?@Barry如果我不是为了委员会的纯洁和傲慢而绝望的话,我会的。