为什么 clang 不使用斐波那契的 constexpr 版本计算斐波那契(500)
Why is clang not computing fibonacci(500) with a constexpr version of fibonacci?
我正在尝试用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;
}
所以我希望lol
编译时计算
toogy@stewie
» g++ -std=c++14 -g src/test.cc -o test.out
toogy@stewie
» ./test.out
4859788740867454402
它与g++
配合得很好。在编译时,它甚至会做一些记忆,优化这个蹩脚的斐波那契函数,然后立即计算fibonacci(500)
。
然后我尝试clang++
:
toogy@stewie
» clang++ -std=c++1y -g src/test.cc -o test.out
toogy@stewie
» ./test.out
... very long
lol
不是在编译时由clang++
计算的(由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.
Clang不能(使用默认编译器标志;尽管我仍然无法让它用-fconstexpr-depth=1000000000
(即10亿))在编译时进行fibonacci(500)
,因此它会在运行时使用您发布的代码进行计算。正如@Streppel链接一样,您可以使用 -fconstexpr-depth=N
编译器标志增加常量表达式的最大递归深度。
然而,第 500 个斐波那契数是巨大的*,所以这肯定会溢出,这是有符号整数的未定义行为(所以所有的赌注都是关闭的,真的)。(但是如果你使用模板元编程,你可以做到这一点)
*如 105 位数字巨大:139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 导入库可以跨dll版本工作吗
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- Qt版本应该在其他计算机上运行吗?
- 为什么CRC计算在C和C 版本之间有所不同
- 如何在一台计算机上同时构建Boost的VC9和VC10版本
- 构建计算机上的C++运行时版本与客户计算机
- 为什么 clang 不使用斐波那契的 constexpr 版本计算斐波那契(500)
- 运行在同一台计算机上编译的程序时,GLIBCXX版本错误
- 有没有一种方法可以在代码中计算出编译器的版本
- 在使用旧版本gcc / glibc / libstdc++的计算机上运行用gcc 4.7编译的c++ 11可执行文件的问
- SSE版本差分平方和算法的累积计算误差
- 如果我的计算机上安装了 g++ 5.1.0 版本,我可以使用 g++-4.7 命令进行编译吗?