在常量表达式上下文中定义之前嵌套的 `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 ,它确实应该按预期工作