Constexpr function does not calculate value at compile time

I want to compare metaprogramming and using constexpr in C ++ 0x. then I write the fib function in both models. when I use the metaprogram model, the response prints out very quickly because it is computed at compile time. but when I use the constexpr function, it calculates the value at runtime, not at compile time. I am using g ++ (gcc) 4.8. Can anyone help me out?

#include <iostream> using namespace std; #define NUM 42 template <unsigned int N> struct Fibonacci { enum { value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value }; }; template <> struct Fibonacci<1> { enum { value = 1 }; }; template <> struct Fibonacci<0> { enum { value = 1 }; }; constexpr unsigned int fib(unsigned int n) { return (n > 1 ? fib(n-1) + fib(n-2) : 1 ); } int main() { cout << "Meta_fib(NUM) : " << Fibonacci<NUM>::value << endl; // compile time :) cout << "Constexpr_fib(NUM) : " << fib(NUM) << endl; // run time :-? return 0; } 
+6
source share
4 answers

I believe the reason is that constexpr not guaranteed to execute at compile time. To provide an estimate of compilation time, you must assign it to compilation aliases. How,

enum {i = fib(NUM)};

+9
source

With gcc, at least you can get the value of constexpr, which will be computed at compile time by making it a static variable:

 static const unsigned fibNUM = fib(NUM); 

When I read the standard, it still allowed me to calculate the value at startup, but in practice it will be computed at compile time.

+4
source

A simple test to make sure your constexpr actually executed at compile time is to use std::array :

 #include <array> std::array<int, Fibonacci<5>::value> arr; std::array<int, fib(5)> arr2; 

gcc has no complaints .

See this comment by Bjarne Straustrup :

... according to the standard, the constexpr function can be evaluated at compiler time or run time if it is not used as a constant expression, in which case it must be evaluated at compile time. To guarantee compilation time, we must either use it where a constant expression is required (for example, as associated with an array or as a case label) or use it to initialize constexpr. I hope that no self-respecting compiler misses the optimization opportunity to do what I originally said: "The constexpr function is evaluated at compile time if all its arguments are constant expressions."

+1
source

constexpr cannot be evaluated at compile time. This means that the compiler can choose whether to evaluate compilation time or at runtime. You can try to assign it to a compile time constant and check how it is ...

 const long i = fib(NUM);// here i should be initialized at the time of // declaration cout << "Meta_fib(NUM) : " << Fibonacci<NUM>::value << endl; cout << "Constexpr_fib(NUM) : " << i << endl; 
+1
source

All Articles