【问题标题】:Rationale for [dcl.constexpr]p5 in the c++ standardc++ 标准中 [dcl.constexpr]p5 的基本原理
【发布时间】:2015-07-28 17:43:41
【问题描述】:

[dcl.constexpr]p5 (http://eel.is/c++draft/dcl.constexpr#5) 的基本原理是什么?

对于非模板、非默认的 constexpr 函数或 非模板、非默认、非继承 constexpr 构造函数,如果 不存在任何参数值,因此调用函数或 构造函数可以是核心常量的求值子表达式 表达式 ([expr.const]),或者,对于构造函数,一个常量 某些对象([basic.start.init])的初始化程序,程序是 格式不正确;无需诊断。

如果一个程序违反了这条规则,那么声明有问题的函数 constexpr 是没有用的。所以呢?接受 decl-specifier constexpr 的无用使用而不是触发未定义的行为(不需要诊断)不是更好吗?除了未定义行为的问题之外,我们还具有在标准中包含规则 [dcl.constexpr]p5 的额外复杂性。

在某些情况下,实现仍然可以提供有用的诊断消息,它能够检测到(按惯例警告)。就像下面的例子一样:

int main() { 0; }

main 中的表达式格式正确但无用。一些编译器无论如何都会以警告的形式发出诊断消息(并且允许它们)。

我知道 [dcl.constexpr]p5 不需要诊断,所以我不问这个。我只是问为什么这个规则甚至在标准中。

【问题讨论】:

  • 这样实现就可以根据需要诊断一个 never-constexpr 函数,但不必特意去做。类似于模板的早期检查。
  • 请在您的问题中包含措辞,链接可能会失效,然后问题就不如参考有用。
  • @T.C Implementations 可以诊断他们想要的任何东西,无需特殊许可。

标签: c++ function language-lawyer constexpr


【解决方案1】:

它格式错误的原因是因为使其格式错误允许实现拒绝不可能形成常量表达式的constexpr 函数定义。尽早拒绝它们意味着获得更多有用的诊断信息。

不需要诊断的原因是因为对于实现来确定对于每个可能的参数组合,结果不是常量表达式可能是不现实的。

格式错误,不需要诊断,实际上意味着与使行为未定义相同的事实在我看来似乎很不幸,但只是因为缺乏更好的选择而被选中。如果意图实际上是允许任何任意运行时行为,我会感到非常惊讶,但是对于 C++ 中的任何语言功能,没有“可能被诊断为错误,但如果不是,则必须按照指定的行为”的概念.

【讨论】:

  • 这个“可能被诊断为错误,但如果不是,则必须按照指定的行为”的概念可以简单地表达为“不可移植”。
  • @n.m.该标准可以以这种方式定义“不可移植”。它可以以这种方式定义几乎任何术语。但这不是通常使用“非便携式”的方式。它的常用方式并没有说明代码在其他实现中的行为方式。它可能会出错,也可能会做一些完全不同的事情。
  • 回应第一部分:使此类程序格式良好,并不妨碍实现提供有用的诊断。格式正确的程序允许诊断消息。编译器通常会为格式良好的程序 int main() { 0; 提供诊断消息。 } 这很好(我是警告的形式)。在这里可以做类似的事情。回应第二部分:是的,我知道。如果存在该规则,则它必须是“不需要诊断”规则,这就是我所关心的。
  • @Supremum 这是一个公平的观点。不幸的是,给出有用的警告,然后跟着一堆无用的错误,这意味着人们在这里询问无用的错误而不看警告,或者至少这是我留下的印象。 :(
  • @Supremum 当前现实世界的实现在实践中要么接受具有合理语义的程序,要么以错误拒绝它。当前现实世界的实施者会认真对待有关不良 QoI 的报告,即使它不会影响一致性。正因为如此,我可以理解有利于信任实施者在这里做正确的事情的权衡。但是,如果实施者确实开始赋予此类程序完全不同的行为,那么我个人的观点就会开始转向你的。
猜你喜欢
  • 2012-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-17
  • 2013-11-24
  • 1970-01-01
相关资源
最近更新 更多