在另一个函数中前向声明“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 scope
和warning: 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”函数——编译器错误?的主要内容,如果未能解决你的问题,请参考以下文章