5
votes

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.

3
what do you mean with "when I use run time" ? Isnt that exactly the same code (minus two lines) ? - 463035818_is_not_a_number
std::cout << fibonacci(32); Its a run time calculation - Hariom Singh
I don't think std::cout << fibonacci(32); is evaluated at runtime unless optimizations are disabled. - MB-F
@kazemakase presently based on memory trace I can say its done at run time - Hariom Singh
@Jean-BaptisteYunès, not really, OP has a bigger issue right now (albeit the bigger issue is arguably closeable as 'typo error') - SergeyA

3 Answers

7
votes
  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).

2
votes

The reason for error is that you are trying to calculate Fib number of Fib number of 32. This is way to much!

You hit the maximum limit of constexpr function recursion, and thus you see a compilation error.

At runtime your program would crash at this point, but it doesn't, because your run-time expression is different - it is a Fib of 32.

-1
votes

If you seriously like to explore runtime vs compile-time, then take a look at template meta-programming. The simple fibonacci example nicely illustrated here: https://medium.com/@milot/fibonacci-sequence-and-c-template-meta-programming-adfa760522ed, blows your solution off the water.