在另一个函数中前向声明“constexpr”函数——编译器错误?

Posted

技术标签:

【中文标题】在另一个函数中前向声明“constexpr”函数——编译器错误?【英文标题】:Forward-declaration of a `constexpr` function inside another function -- Compiler bug? 【发布时间】:2016-09-28 08:24:33 【问题描述】:

在为我偶然发现的this 问题生成 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;

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

error: 'constexpr int f()' used before its definition

注释掉 // 2 和取消注释 // 1 对这两种编译器都有效。

有趣的是,将f 的定义移动到// 1 的位置会编译,但会在// 2 处触发警告:

warning: inline function 'constexpr int f()' used but never defined

哪个编译器是正确的?

【问题讨论】:

标准对此似乎不太清楚。我们这里需要一位强大的律师 :) 【参考方案1】:

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

在这种情况下,使用声明 2,GCC 抱怨: warning: 'inline' specifier invalid for function 'f' declared out of global scopewarning: inline function 'int f()' used but never defined。 链接失败(“undefined reference to 'f()'”)。

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

Clang 抱怨: error: inline declaration of 'f' not allowed in block scope

由于constexpr 隐含inline,看来块范围内不允许内联声明的规则也应该适用于constexpr,所以GCC 是正确的。但标准似乎并没有出来说这个。在我审查的草案中,关于 inline 的规则在 §7.1.2 [dcl.fct.spec],第 3 部分:“内联说明符不应出现在块范围函数声明中”,但没有类似的出现 @ 987654334@.

【讨论】:

以上是关于在另一个函数中前向声明“constexpr”函数——编译器错误?的主要内容,如果未能解决你的问题,请参考以下文章

在 Objective-C 中前向声明枚举

C编程中前向声明的意义是啥?

在 libc++ 的内联命名空间中前向声明类的可移植方式是啥?

为啥**不**将函数声明为`constexpr`?

我可以用 constexpr 函数声明一个静态数组吗

在另一个文件c ++中的前向声明