gpt4 book ai didi

c++ - 为什么 clang 不使用斐波那契的 constexpr 版本计算 fibonacci(500)?

转载 作者:太空狗 更新时间:2023-10-29 20:03:38 25 4
gpt4 key购买 nike

我正在尝试使用 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 的最大递归深度。您可以通过将 lol 设为 constexpr 来强制在编译时对其求值,即:

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 个斐波那契数很大*,所以这肯定会溢出,这是有符号整数的未定义行为(所以所有的赌注都没有了,真的)。 ( But you can do it if you use template metaprogramming )

* as in 105 digits huge : 1394232245616978801397243828704072839500702565876973072641089629483255716228632906915557658876222521294125

关于c++ - 为什么 clang 不使用斐波那契的 constexpr 版本计算 fibonacci(500)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27320183/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com