【问题标题】:Why disallow goto in constexpr functions?为什么在 constexpr 函数中不允许 goto?
【发布时间】:2017-12-29 05:05:51
【问题描述】:

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

【问题讨论】:

  • 这是非常不可预测的,即使对于编译器也是如此。
  • @user0042 goto 仍然有它的用途,它是一个有效且需要的构造
  • @user0042 我不这么认为。你要破坏的代码量可能是巨大的。此外,goto 确实有其罕见的用途——比如打破深度嵌套循环的多层。我的信念是goto 不是一个糟糕的构造因此 - 你应该非常非常小心 在你使用它的地方(通常你不应该)。
  • @user0042:Böhm-Jacopini 定理告诉你,你总是可以替换 goto,但代价是什么?一个很好的 goto 用于打破深度嵌套循环或用于 C 风格的错误清理通常比结构化编程解决方法更清晰。
  • 你们可以继续讨论这个话题吗?这里不是讨论“goto 利弊”的地方。

标签: c++ c++14 language-lawyer constexpr goto


【解决方案1】:

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

也就是说,确实存在这样一种观点,即在constexpr 上下文中包含goto 既有用又可能。确实,用于放松的initial proposal constexpr 允许它。因此,也许只需要有人希望它写一个提案来添加它。那个人可能是你!显然是两年前在N4472中的Ville Voutilainen,其中包含与这个问题相当相关的段落:

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

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

【讨论】:

  • 当然,但在某些时候有人不得不说“好吧,for-loops 很好,但是一般goto 有问题”。为什么要分叉治疗?什么会使goto 更具争议性、难度或[其他形容词]?
  • @T.C.谢谢!你会认为我会找到标题为“constexpr goto”的论文......
  • @Barry C++11 constexpr 遵循函数调用的宏扩展。如果这样的扩展表达式是,它们是常量表达式。没有这样的逻辑来禁止 goto 而允许突变和循环,这显然至少难以实现。这是政治正确,句号。
  • @curiousguy 你打算写一篇建议 constexpr goto 的论文吗?
  • @Barry 如果我对委员会的纯洁和傲慢没有绝望,我会的。
【解决方案2】:

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

【讨论】:

  • 构建 AST 会变得多么复杂?整个翻译单元的 AST 肯定会在编译器开始考虑 constexpr 评估之前构建。毕竟,该评估不会影响解析。
  • @Sneftel 编译器评估 constexpr 值的时间取决于实现(它必须在前端阶段完成)但如果 AST 是基本的,具有明显的评估顺序,节点之间没有跳转。
  • C++ 是一种抽象语言,其特性是否“易于”实现完全不在标准范围内。例如,异常不容易在语言中实现。
  • @black:“其功能是否“易于”实现完全不在标准的考虑范围内。”不,不是。标准委员会经常考虑实施特定功能的实施成本是否值得用户为该功能获得收益。这是旧的 C++0x 概念消亡的原因之一。而缺乏这种考虑就是 C++98 export 惨败发生的原因。
  • @NicolBolas 惨败的发生是因为 MS 反对 export,基于传闻和荒谬的说法。
猜你喜欢
  • 2017-05-27
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 2015-03-21
  • 2023-03-27
相关资源
最近更新 更多