Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fibonacci using constexpr function (compile time vs run time)

Tags:

c++

I am using constexpr to get the Fibonacci number

Enumeration is used to calculate the fibonacci in compile time

#include <iostream>

constexpr long fibonacci(long long  n)
{
    return n < 1 ? -1 :
        (n == 1 || n == 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2));
}

enum Fibonacci
{
    Ninth =    fibonacci(9),
    Tenth =    fibonacci(10),
    Thirtytwo = fibonacci(32)

};

int main()
{
    std::cout << Fibonacci(Thirtytwo);
   // std::cout << fibonacci(32);
    return 0;
}

I am getting the following error on execution:

1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12): note: while evaluating 'fibonacci(30)'
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(6): note: while evaluating 'fibonacci(31)'
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12): note: while evaluating 'fibonacci(31)'
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12): error C2131: expression did not evaluate to a constant
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(5): note: failure was caused by control reaching the end of a constexpr function
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12): note: while evaluating 'fibonacci(32)'
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(14): error C2057: expected constant expression
1>Done building project "ConsoleApplication4.vcxproj" -- FAILED.

But when I use run time int x=30, y=2; std::cout << fibonacci(x+y);//fibonacci is calculated on run time

Run Time with memory

I won't say I have a question but I have few confusions like:

  1. Is memory used by compile time and run time use of constexpr different?
  2. How do I know where to stop exploiting or using compile time data?
  3. Which I am still trying to do is how to do Fibo-like calculation using both the advantage of compile time and run time together (use compile till it can be and after that let rest of calculation be done on run time).

Any example or reference if available will be helpful.

like image 429
Hariom Singh Avatar asked Aug 10 '17 14:08

Hariom Singh


People also ask

Does Constexpr compile time?

constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time.

Is Constexpr always evaluated at compile time?

A constexpr function that is eligible to be evaluated at compile-time will only be evaluated at compile-time if the return value is used where a constant expression is required. Otherwise, compile-time evaluation is not guaranteed.


1 Answers

  1. Memory used by the constexpr function at compile time is implementation dependent, but in general should be comparable to runtime (most compilers will compile and execute the statement).

  2. In theory, you should use compile time evaluated expressions whenever possible. In practice, it's a judgment call (perhaps a good topic for an SE question), as the down sides are increased compile time (and perhaps memory) and lack of debugging.

  3. It appears you are reaching the maximum recursion limit allowed by MSVC in compile time expressions. I can't find any documentation on what this limit is, but it's configurable on other compilers. Your error is the result of the enum requiring it to be fully evaluated at compile time, where as the cout call allows it be executed at compile time and/or run time (if you generate assembly, you should see compile time constants generated for the lower number calls, and a recursive function being used for the high number calls).

like image 56
dlasalle Avatar answered Oct 16 '22 20:10

dlasalle