[英]Nested `constexpr` function calls before definition in a constant-expression context
From what I gather from this answer , a constexpr
function's result is not a constant-expression if the function has not been declared yet. 根据我从这个答案收集的内容,如果函数尚未声明,则
constexpr
函数的结果不是常量表达式。 What surprises me is the following code snippet : 令我惊讶的是以下代码片段:
constexpr int f();
constexpr int g() {
return f();
}
constexpr int f() {
return 42;
}
int main() {
constexpr int i = g();
return i;
}
This compiles without trouble and works. 这编译没有麻烦和工作。 Moving
f
's definition past main triggers error: 'constexpr int f()' used before its definition
, as I would expect. 移动
f
的定义超过主要触发器error: 'constexpr int f()' used before its definition
,正如我所料。
I presume that it works because f
has been defined before the call to g
, thus both calls are constant expressions. 我认为它的工作原理是因为在调用
g
之前定义了f
,因此两个调用都是常量表达式。
Why are f()
and g()
apparently constant-expressions, even though f
isn't defined when it is called by g
? 为什么
f()
和g()
显然是常量表达式,即使f
在被g
调用时没有定义f
? How is this described by the Standard? 标准如何描述?
I have tested this on Coliru's GCC 6.1.0 and Clang 3.8.0. 我在Coliru的GCC 6.1.0和Clang 3.8.0上测试了这个。
It is not necessary to define a constexpr
before it is used. 在使用
constexpr
之前没有必要定义它。 However, the result of calling it before its definition is not constexpr
. 但是,在定义之前调用它的结果不是
constexpr
。 Consequently, the compiler rightfully complains because you're trying to initialize a constexpr
variable with a non-constant expression. 因此,编译器正确地抱怨,因为您尝试使用非常量表达式初始化
constexpr
变量。
§5.20/p2 Constant expressions [expr.const] ( Emphasis Mine ) : §5.20/ p2常量表达式[expr.const] ( 强调我的 ):
A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
条件表达式e是核心常量表达式,除非根据抽象机器(1.9)的规则评估e将评估以下表达式之一:
...
...
(2.3) — an invocation of an undefined constexpr function or an undefined constexpr constructor;
(2.3) - 调用未定义的constexpr函数或未定义的constexpr构造函数;
As linked by TC in his comment , this is subject to a defect report . 由TC在其评论中链接,这是一个缺陷报告 。
According to 5.20 [expr.const] bullet 2.3, an expression is a constant expression unless (among other reasons) it would evaluate
根据5.20 [expr.const] bullet 2.3,表达式是一个常量表达式,除非(以及其他原因)它将进行评估
- an invocation of an undefined
constexpr
function or an undefinedconstexpr
constructor;调用未定义的
constexpr
函数或未定义的constexpr
构造函数;This does not address the question of the point at which a
constexpr
function must be defined.这没有解决必须定义
constexpr
函数的问题。 The intent, in order to allow mutually-recursiveconstexpr
functions, was that the function must be defined prior to the outermost evaluation that eventually results in the invocation, but this is not clearly stated.为了允许相互递归的
constexpr
函数,意图是必须在最外部评估之前定义函数,最终导致调用,但这没有明确说明。
This makes it clear that the example is well-formed and should indeed work as expected as long as f
is defined before the call to g
. 这清楚地表明,只要在调用
g
之前定义了f
,该示例就是格式良好的,并且确实应该按预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.