[英]Forward-declaration of a `constexpr` function inside another function — Compiler bug?
虽然我偶然发现了这个问题的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
哪个编译器是对的?
用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
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部分:“内联说明符不应出现在块作用域函数声明中”,但是关于constexpr
没有类似的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.