c++ 标准中 [dcl.constexpr]p5 的基本原理
Rationale for [dcl.constexpr]p5 in the c++ standard
[dcl.constexpr]p5 (http://eel.is/c++draft/dcl.constexpr#5) 的基本原理是什么?
For a non-template, non-defaulted constexpr function or a
non-template, non-defaulted, non-inheriting constexpr constructor, if
no argument values exist such that an invocation of the function or
constructor could be an evaluated subexpression of a core constant
expression ([expr.const]), or, for a constructor, a constant
initializer for some object ([basic.start.init]), the program is
ill-formed; no diagnostic required.
如果一个程序违反了这个规则,声明违规函数 constexpr 是没有用的。所以呢?接受声明说明符 constexpr 的无用使用而不是触发未定义的行为(不需要诊断)不是更好吗?除了未定义行为的问题之外,我们还有标准中的规则 [dcl.constexpr]p5 的额外复杂性。
在某些情况下,实现仍然可以提供它能够检测到的有用诊断消息(按照约定发出警告)。就像下面的情况:
int main() { 0; }
main 中的表达式格式正确但无用。一些编译器无论如何(并且允许它们)以警告的形式发出诊断消息。
我知道 [dcl.constexpr]p5 不需要诊断,所以我不是问这个。我只是问为什么这个规则甚至在标准中。
它格式错误的原因是因为使其格式错误允许实现拒绝 constexpr
不可能形成常量表达式的函数定义。尽早拒绝它们意味着获得更有用的诊断。
之所以不需要诊断,是因为对于实现来说,确定每个可能的参数组合的结果都不是常量表达式可能是不现实的。
事实上,格式错误,不需要诊断,实际上意味着与未定义行为相同的事情在我看来似乎是不幸的,但只是因为缺乏更好的选择而被选中。如果意图实际上是允许任何任意 运行 时间行为,我会感到非常惊讶,但是 C++ 中的任何语言特性都没有 "may be diagnosed as an error, but if not, must behave as specified" 的概念。
[dcl.constexpr]p5 (http://eel.is/c++draft/dcl.constexpr#5) 的基本原理是什么?
For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression ([expr.const]), or, for a constructor, a constant initializer for some object ([basic.start.init]), the program is ill-formed; no diagnostic required.
如果一个程序违反了这个规则,声明违规函数 constexpr 是没有用的。所以呢?接受声明说明符 constexpr 的无用使用而不是触发未定义的行为(不需要诊断)不是更好吗?除了未定义行为的问题之外,我们还有标准中的规则 [dcl.constexpr]p5 的额外复杂性。
在某些情况下,实现仍然可以提供它能够检测到的有用诊断消息(按照约定发出警告)。就像下面的情况:
int main() { 0; }
main 中的表达式格式正确但无用。一些编译器无论如何(并且允许它们)以警告的形式发出诊断消息。
我知道 [dcl.constexpr]p5 不需要诊断,所以我不是问这个。我只是问为什么这个规则甚至在标准中。
它格式错误的原因是因为使其格式错误允许实现拒绝 constexpr
不可能形成常量表达式的函数定义。尽早拒绝它们意味着获得更有用的诊断。
之所以不需要诊断,是因为对于实现来说,确定每个可能的参数组合的结果都不是常量表达式可能是不现实的。
事实上,格式错误,不需要诊断,实际上意味着与未定义行为相同的事情在我看来似乎是不幸的,但只是因为缺乏更好的选择而被选中。如果意图实际上是允许任何任意 运行 时间行为,我会感到非常惊讶,但是 C++ 中的任何语言特性都没有 "may be diagnosed as an error, but if not, must behave as specified" 的概念。