在常量表达式上下文中定义之前嵌套的 `constexpr` 函数调用
Nested `constexpr` function calls before definition in a constant-expression context
根据我从 收集到的信息,如果函数尚未声明,constexpr
函数的结果不是常量表达式。令我惊讶的是以下代码片段:
constexpr int f();
constexpr int g() {
return f();
}
constexpr int f() {
return 42;
}
int main() {
constexpr int i = g();
return i;
}
这个编译没有问题并且可以工作。正如我所料,将 f
的定义移到主要触发器 error: 'constexpr int f()' used before its definition
之后。
我认为它可以工作,因为 f
在调用 g
之前已经定义,因此两个调用都是常量表达式。
为什么 f()
和 g()
显然是常量表达式,即使 f
在被 g
调用时未定义?标准是如何描述的?
我已经在 Coliru 的 GCC 6.1.0 和 Clang 3.8.0 上对此进行了测试。
在使用前不需要定义constexpr
。但是,在它的定义之前调用它的结果不是constexpr
。因此,编译器会合理地抱怨,因为您试图用非常量表达式初始化 constexpr
变量。
§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:
...
(2.3) — an invocation of an undefined constexpr function or an
undefined constexpr constructor;
由 T.C 链接。在 , this is subject to a defect report.
According to 5.20 [expr.const] bullet 2.3, an expression is a constant
expression unless (among other reasons) it would evaluate
- an invocation of an undefined
constexpr
function or an undefined constexpr
constructor;
This does not address the question of the point at which a constexpr
function must be defined. The intent, in order to allow
mutually-recursive constexpr
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.
这清楚地表明该示例格式正确,只要在调用 g
.
之前定义 f
,它确实应该按预期工作
根据我从 constexpr
函数的结果不是常量表达式。令我惊讶的是以下代码片段:
constexpr int f();
constexpr int g() {
return f();
}
constexpr int f() {
return 42;
}
int main() {
constexpr int i = g();
return i;
}
这个编译没有问题并且可以工作。正如我所料,将 f
的定义移到主要触发器 error: 'constexpr int f()' used before its definition
之后。
我认为它可以工作,因为 f
在调用 g
之前已经定义,因此两个调用都是常量表达式。
为什么 f()
和 g()
显然是常量表达式,即使 f
在被 g
调用时未定义?标准是如何描述的?
我已经在 Coliru 的 GCC 6.1.0 和 Clang 3.8.0 上对此进行了测试。
在使用前不需要定义constexpr
。但是,在它的定义之前调用它的结果不是constexpr
。因此,编译器会合理地抱怨,因为您试图用非常量表达式初始化 constexpr
变量。
§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:
...
(2.3) — an invocation of an undefined constexpr function or an undefined constexpr constructor;
由 T.C 链接。在
According to 5.20 [expr.const] bullet 2.3, an expression is a constant expression unless (among other reasons) it would evaluate
- an invocation of an undefined
constexpr
function or an undefinedconstexpr
constructor;This does not address the question of the point at which a
constexpr
function must be defined. 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.
这清楚地表明该示例格式正确,只要在调用 g
.
f
,它确实应该按预期工作