在另一个函数内转发声明`constexpr`函数 - 编译错误?

Que*_*tin 9 c++ language-lawyer compiler-bug function-declaration constexpr

虽然我偶然发现了这个问题的MCVE ,但我发现编译器之间存在以下差异:

请考虑以下代码:

// constexpr int f(); // 1

constexpr int g() {
    constexpr int f(); // 2
    return f();
}

constexpr int f() {
    return 42;
}

int main() {
    constexpr int i = g();
    return i;
}
Run Code Online (Sandbox Code Playgroud)

此代码在Clang 3.8.0上编译,但在GCC 6.1.0上失败:

error: 'constexpr int f()' used before its definition
Run Code Online (Sandbox Code Playgroud)

在两个编译器上评论// 2和取消注释// 1.

有趣的是,移动f的定义代替了// 1编译,但在// 2以下情况下触发了警告:

warning: inline function 'constexpr int f()' used but never defined
Run Code Online (Sandbox Code Playgroud)

哪个编译器是对的?

Nic*_*teo 2

constexpr用函数替换函数inline会保留完全相同的问题(全局声明 1 可以,但函数范围声明 2 不行。)Sinceconstexpr暗示inline这似乎是原因。

\n\n

在这种情况下,对于声明 2,GCC 会抱怨:\n warning: \'inline\' specifier invalid for function \'f\' declared out of global scope\nand warning: inline function \'int f()\' used but never defined。\n它无法链接 (" undefined reference to \'f()\'")。

\n\n

所以看起来它放弃了内联,进行了调用,但不费心发出代码,因为f()所有使用都是内联的(?),所以链接失败。

\n\n

Clang 抱怨道:\nerror: inline declaration of \'f\' not allowed in block scope

\n\n

既然constexpr暗示了inline,似乎块作用域中不允许内联声明的规则也应该适用于constexpr,因此 GCC 是正确的。但标准似乎并没有出来这么说。在我检查的草案中,有关的规则inline位于 \xc2\xa77.1.2 [dcl.fct.spec],第 3 部分:“内联说明符不得出现在块作用域函数声明中”,但没有出现类似的内容constexpr

\n