简体   繁体   English

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

[英]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 scopewarning: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM