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

时间:2016-05-30 13:22:47

标签: c++ language-lawyer constexpr function-declaration compiler-bug

在为this问题产生MCVE时我偶然发现,我发现编译器之间存在以下差异:

请考虑以下代码:

Global.asax

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

// 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;
}

评论error: 'constexpr int f()' used before its definition 并取消注释// 2适用于两个编译器。

有趣的是,移动// 1的定义代替f编译,但会在// 1处触发警告:

// 2

哪种编译器是对的?

1 个答案:

答案 0 :(得分:2)

constexpr函数替换inline函数会保留完全相同的问题(可以使用全局声明1,但不能使用函数范围声明2.)自constexpr以来暗示inline这似乎是原因。

在这种情况下,通过声明2,海湾合作委员会抱怨: 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部分:“内联说明符不应出现在块作用域函数声明中”,但没有出现类似内容关于constexpr