C++ 为什么clang不使用fibonacci的constexpr版本计算fibonacci(500)?
我在尝试使用C++ 为什么clang不使用fibonacci的constexpr版本计算fibonacci(500)?,c++,g++,clang++,C++,G++,Clang++,我在尝试使用constexpr: #include <iostream> constexpr long long fibonacci(const int x) { return x <= 1 ? 1 : fibonacci(x - 1) + fibonacci(x - 2); } int main() { const long long lol = fibonacci(500); std::cout << lol << std
constexpr
:
#include <iostream>
constexpr long long fibonacci(const int x)
{
return x <= 1 ? 1 : fibonacci(x - 1) + fibonacci(x - 2);
}
int main()
{
const long long lol = fibonacci(500);
std::cout << lol << std::endl;
}
它在g++
上运行得非常好。在编译时,它甚至会进行一些记忆,优化这个糟糕的fibonnaci函数,然后立即计算fibonacci(500)
然后我尝试使用clang++
:
toogy@stewie
» clang++ -std=c++1y -g src/test.cc -o test.out
toogy@stewie
» ./test.out
... very long
glang++
在编译时不计算lol
(由gdb
证明)为什么?它达到了clang的最大递归深度。您可以通过使constexpr
在编译时强制计算lol
,即:
constexpr long long lol = fibonacci(500);
执行此操作并使用clang++-std=c++11 t.cpp进行编译会产生以下错误:
t.cpp:10:25: error: constexpr variable 'lol' must be initialized by a constant
expression
constexpr long long lol = fib(500);
^ ~~~~~~~~
t.cpp:4:1: note: constexpr evaluation hit maximum step limit; possible infinite
loop?
{
^
t.cpp:5:38: note: in call to 'fib(4)'
return x <= 1 ? 1 : fib(x - 1) + fib(x - 2);
^
t.cpp:5:25: note: in call to 'fib(6)'
return x <= 1 ? 1 : fib(x - 1) + fib(x - 2);
^
t.cpp:5:38: note: in call to 'fib(7)'
return x <= 1 ? 1 : fib(x - 1) + fib(x - 2);
^
t.cpp:5:25: note: in call to 'fib(9)'
return x <= 1 ? 1 : fib(x - 1) + fib(x - 2);
^
t.cpp:5:25: note: in call to 'fib(10)'
t.cpp:5:25: note: (skipping 480 calls in backtrace; use
-fconstexpr-backtrace-limit=0 to see all)
t.cpp:5:25: note: in call to 'fib(496)'
t.cpp:5:25: note: in call to 'fib(497)'
t.cpp:5:25: note: in call to 'fib(498)'
t.cpp:5:25: note: in call to 'fib(499)'
t.cpp:10:31: note: in call to 'fib(500)'
constexpr long long lol = fib(500);
^
1 error generated.
t.cpp:10:25:错误:constexpr变量'lol'必须由常量初始化
表达
constexpr long lol=fib(500);
^ ~~~~~~~~
t、 cpp:4:1:注:constexpr评估达到最大步长限制;可能无限
环
{
^
t、 cpp:5:38:注:调用“fib(4)”时
return x也是,g++正在计算一些东西,但不是第500个斐波那契数。它溢出的速度非常快。即使是第30个数也不适合长的长度。根据,constexpr递归调用的默认深度是512。因此我想这没有什么问题。我认为可能是整数溢出,正如@Cornst所提到的alksAlso,clang/gcc可能检测到一些溢出,并且由于有符号整数溢出是未定义的行为,它们可能会产生不同的结果。(假设第500个斐波那契数是)@Cornstalks lol,是的……这一个溢出的机会很大。
t.cpp:10:25: error: constexpr variable 'lol' must be initialized by a constant
expression
constexpr long long lol = fib(500);
^ ~~~~~~~~
t.cpp:4:1: note: constexpr evaluation hit maximum step limit; possible infinite
loop?
{
^
t.cpp:5:38: note: in call to 'fib(4)'
return x <= 1 ? 1 : fib(x - 1) + fib(x - 2);
^
t.cpp:5:25: note: in call to 'fib(6)'
return x <= 1 ? 1 : fib(x - 1) + fib(x - 2);
^
t.cpp:5:38: note: in call to 'fib(7)'
return x <= 1 ? 1 : fib(x - 1) + fib(x - 2);
^
t.cpp:5:25: note: in call to 'fib(9)'
return x <= 1 ? 1 : fib(x - 1) + fib(x - 2);
^
t.cpp:5:25: note: in call to 'fib(10)'
t.cpp:5:25: note: (skipping 480 calls in backtrace; use
-fconstexpr-backtrace-limit=0 to see all)
t.cpp:5:25: note: in call to 'fib(496)'
t.cpp:5:25: note: in call to 'fib(497)'
t.cpp:5:25: note: in call to 'fib(498)'
t.cpp:5:25: note: in call to 'fib(499)'
t.cpp:10:31: note: in call to 'fib(500)'
constexpr long long lol = fib(500);
^
1 error generated.