[英]Forward-declaration of a `constexpr` function inside another function — Compiler bug?
While producing a MCVE for this problem I stumbled upon, I've found the following discrepancy between compilers: 虽然我偶然发现了这个问题的MCVE,但我发现编译器之间存在以下差异:
Consider the following code : 请考虑以下代码:
// 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;
}
This code compiles on Clang 3.8.0, but fails on GCC 6.1.0 with: 此代码在Clang 3.8.0上编译,但在GCC 6.1.0上失败:
error: 'constexpr int f()' used before its definition
Commenting out // 2
and uncommenting // 1
works on both compilers. 注释// 2
并取消注释// 1
适用于两个编译器。
Interestingly, moving f
's definition in place of // 1
compiles, but triggers a warning at // 2
: 有趣的是,移动f
的定义代替// 1
编译,但在// 2
处触发警告:
warning: inline function 'constexpr int f()' used but never defined
Which compiler is right ? 哪个编译器是对的?
Replacing the constexpr
functions with inline
functions retains the exact same problem (it is okay with the global declaration 1, but not with the function-scope declaration 2.) Since constexpr
implies inline
this seems like the cause. 用inline
函数替换constexpr
函数会保留完全相同的问题(可以使用全局声明1,但不能使用函数范围声明2.)因为constexpr
暗示inline
这似乎是原因。
In this case, with declaration 2, GCC complains: warning: 'inline' specifier invalid for function 'f' declared out of global scope
and warning: inline function 'int f()' used but never defined
. 在这种情况下,使用声明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
。 It fails to link (" undefined reference to 'f()'
"). 它无法链接(“ undefined reference to 'f()'
”)。
So it looks like it gives up on inlining, puts in a call, but doesn't bother emitting code for f()
because all uses are inlined (?), so the link fails. 所以看起来它放弃了内联,放入一个调用,但是没有为f()
发出代码,因为所有的用法都是内联的(?),所以链接失败了。
and Clang complains: error: inline declaration of 'f' not allowed in block scope
和Clang抱怨: error: inline declaration of 'f' not allowed in block scope
Since constexpr
implies inline
, it seems that this rule that inline declarations are not allowed in block scope should also apply to constexpr
, and so GCC is correct. 由于constexpr
意味着inline
,似乎这个规则在块范围内不允许内联声明也应该适用于constexpr
,因此GCC是正确的。 But the standard does not seem to come out and say this. 但标准似乎没有出来说这个。 In the draft I examined, the rule about inline
is in §7.1.2 [dcl.fct.spec], part 3: "The inline specifier shall not appear on a block scope function declaration", but nothing similar appears about constexpr
. 在我检查的草案中,关于inline
的规则在§7.1.2[dcl.fct.spec]中,第3部分:“内联说明符不应出现在块作用域函数声明中”,但是关于constexpr
没有类似的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.