c++ - 为什么 gcc5.4 不编译调用非 constexpr 函数的 constexpr 函数,但 icpc 却编译?

标签 c++ gcc constexpr icc

gcc5.4 无法编译以下代码:

// source.cpp
int nonconstexprfunc()
{
    return 14;
}

constexpr int func(int n)
{
    if (n < 0)
        return nonconstexprfunc();
    return n*n;
}

int main()
{
    constexpr int t1 = func(0);
    return 0;
}

我使用的命令:

$ g++ -std=c++14 -c source.cpp

输出:

In function ‘constexpr int func(int)’:
error: ‘constexpr int func(int)’ called in a constant expression
constexpr int t1 = func(0);
In function ‘int main()’:
error: ‘constexpr int func(int)’ called in a constant expression
constexpr int t1 = func(0);

但我可以使用 gcc6.4 编译该 source.cpp。 gcc5.4不是完全支持constexpr函数了吗?

更有趣的是,我可以使用使用 gcc5.4 的 icpc(英特尔 C++ 编译器)编译该 source.cpp - 我想必须有一个选项来使用 gcc5.4 编译该代码。

$  icpc -v
icpc version 19.0 (gcc version 5.4.0 compatibility)
$  icpc -std=c++14 -c source.cpp
no errors

最佳答案

第一个限制是关于使用带有 -std=c++11 的 gcc 5.4,它会由于两个 return 语句而产生错误,请参阅 The body of constexpr function not a return-statement因此,为了解决您的第一个问题,您需要使用 -std=c++14

然后它会产生

'#1 with x86-64 gcc 5.4 : In function 'constexpr int func(int)':

:10:32: error: call to non-constexpr function 'int nonconstexprfunc()'

     return nonconstexprfunc();        ^

: In function 'int main()':

:16:28: error: 'constexpr int func(int)' called in a constant expression

 constexpr int t1 = func(0);

                         Compiler returned: 1

产生的下一个错误似乎是一个已知的 GCC 错误(对 c++14 的误解)请参阅
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86678
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67026

您还可以查看calling non constexpr function from constexpr allowed in some conditions

但是从它产生的错误来看:

看起来很明显,这样做

constexpr int nonconstexprfunc()
{
    return 14;
}

将解决错误,并且在您的情况下会更有效。
使用 https://www.godbolt.org/ 检查差异例如,添加 constexpr 或不使用 gcc 8.2。

关于c++ - 为什么 gcc5.4 不编译调用非 constexpr 函数的 constexpr 函数,但 icpc 却编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54326901/

相关文章:

c++ - C++ 中的 const 双表达式

c++ - constexpr 标准仿函数的正确用法是什么?

c++ - 带有 g++ (Ubuntu) 的 virtual 关键字的奇怪 (?) 行为

c# - 温习 C++、C#、ASP.NET 和设计模式的知识

gcc - 在Fedora上使用Gold代替ld作为系统链接器

gcc - 使用 gcc < 5 抑制 AVX 内联汇编错误

c++ - C++11 和 C++14 中的 constexpr(与 const 关键字没有区别)

c++ - nm 命令中的 "symbol value"是什么意思?

c++ - C++ 中的舍入和往返数字

c++ - 我可以在 C++03 和 C++11 中使用 C 可变长度数组吗?