When I execute this code, the result change between two execution but I don't understand why. sometimes the results for u/v/w/x are "u 46368 <0ms, soit 0 ns>" OR "u 46368 <1ms, soit 1000100 ns> and this is random. But when a fonction is constexpr the evaluation must be do at the compile time. But here sometime is do at the compile time and sometime at the runtime.
The other question is why for the point w and x the evaluation is sometime at the compile time because the variables are not constexpr.
#include <iostream>
#include <chrono>
using namespace std;
#define CPP14 0
#define CONSTEXPR_FCT !0
#if CONSTEXPR_FCT
constexpr unsigned fibonacci(unsigned nb)
#else
unsigned fibonacci(unsigned nb)
#endif
{
#if !CPP14
return ((nb == 1) ? 1 : ((nb == 0) ? 0 :
fibonacci(nb - 2) + fibonacci(nb - 1)));
#else
if (nb == 1)
{
return 1;
}
else if (nb == 0)
{
return 0;
}
else
{
return fibonacci(nb - 2) + fibonacci(nb - 1);
}
#endif
}
int main()
{
cout << "a) ";
for (unsigned u { 0 }; u < 10; ++u)
{
cout << fibonacci(u) << " ";
}
cout << endl;
constexpr unsigned depth { 24u };
// 24u : limite de profondeur recursive avec clang++ 4.0.1
cout << "\nb) u : ";
cout.flush(); // flush... sans passage a la ligne !
auto start = chrono::high_resolution_clock::now();
// inference de type : plus tard !
unsigned u { fibonacci(depth) };
auto end = chrono::high_resolution_clock::now();
cout << u << " (" <<
chrono::duration_cast<chrono::milliseconds>(end - start).count()
<< " ms, soit " <<
chrono::duration_cast<chrono::nanoseconds>(end - start).count()
<< " ns)" << endl;
// -----------------
cout << "c) v : ";
cout.flush();
start = chrono::high_resolution_clock::now();
unsigned v { fibonacci(depth) };
end = chrono::high_resolution_clock::now();
cout << v << " (" <<
chrono::duration_cast<chrono::milliseconds>(end - start).count()
<< " ms, soit " <<
chrono::duration_cast<chrono::nanoseconds>(end - start).count()
<< " ns)" << endl;
// -----------------
#if CONSTEXPR_FCT
cout << "d) cxu : ";
cout.flush();
start = chrono::high_resolution_clock::now();
constexpr unsigned cxu { fibonacci(depth) };
end = chrono::high_resolution_clock::now();
cout << cxu << " (" <<
chrono::duration_cast<chrono::nanoseconds>(end - start).count() << " ns)" << endl;
#endif
// -----------------
cout << "e) w : ";
cout.flush();
start = chrono::high_resolution_clock::now();
unsigned w { fibonacci(depth) };
end = chrono::high_resolution_clock::now();
cout << w << " (" <<
chrono::duration_cast<chrono::milliseconds>(end - start).count() << " ms, soit " <<
chrono::duration_cast<chrono::nanoseconds>(end - start).count() << " ns)" << endl;
// -----------------
cout << "f) cu : ";
cout.flush();
start = chrono::high_resolution_clock::now();
const unsigned cu { fibonacci(depth) };
end = chrono::high_resolution_clock::now();
cout << cu << " (" << chrono::duration_cast<chrono::nanoseconds>(end-start).count() << " ns)" << endl;
// -----------------
cout << "e) x : ";
cout.flush();
start = chrono::high_resolution_clock::now();
unsigned x { fibonacci(depth) };
end = chrono::high_resolution_clock::now();
cout << x << " (" <<
chrono::duration_cast<chrono::milliseconds>(end - start).count() << " ms, soit " << chrono::duration_cast<chrono::nanoseconds>(end - start).count() << " ns)" << endl;
return 0;
}
The output is:
a) 0 1 1 2 3 5 8 13 21 34
b) u 46368 <1ms, soit 1000100ns> or u 46368 <0ms, soit 0 ns>
c) v 46368 <1ms, soit 1000100ns> or v 46368 <0ms, soit 0 ns>
d) cxu : 46368 <0 ns>`enter code here`
e) w 46368 <1ms, soit 1000100ns> or w 46368 <0ms, soit 0 ns>
f) cu : 46368 <0ns>
e) x 46368 <1ms, soit 1000100ns> or x 46368 <0ms, soit 0 ns>