Thanks, I do not need any book to teach me what constexpr
means. I am teaching constexpr
and my simple example fails convincing students why they should use the advantage of compile time computation via constexpr
.
Also please strictly avoid linking to questions such as this which has no assembly code or profiling and they are meaningless for my question.
I am looking for an example to show why constexpr
is useful at all and it cannot be dismissed.
Well, in many cases if constexpr
is replaced by const
nothing wrong really happens. So, I designed the following examples:
main_const.cpp
#include <iostream>
using namespace std;
const int factorial(int N)
{
if(N<=1)
return 1;
else
return N*factorial(N-1);
}
int main()
{
cout<<factorial(10)<<endl;
return 0;
}
and
main_constexpr.cpp
#include <iostream>
using namespace std;
constexpr int factorial(int N)
{
if(N<=1)
return 1;
else
return N*factorial(N-1);
}
int main()
{
cout<<factorial(10)<<endl;
return 0;
}
But the problem is that for them former one, the assembly code is
main_const.asm
12:main_last.cpp **** int main()
13:main_last.cpp **** {
132 .loc 1 13 0
133 .cfi_startproc
134 0000 4883EC08 subq $8, %rsp
135 .cfi_def_cfa_offset 16
14:main_last.cpp **** cout<<factorial(10)<<endl;
136 .loc 1 14 0
137 0004 BE005F37 movl $3628800, %esi
137 00
138 0009 BF000000 movl $_ZSt4cout, %edi
138 00
139 000e E8000000 call _ZNSolsEi
And for the latter one it is
main_constexpr.asm
12:main_now.cpp **** int main()
13:main_now.cpp **** {
11 .loc 1 13 0
12 .cfi_startproc
13 0000 4883EC08 subq $8, %rsp
14 .cfi_def_cfa_offset 16
14:main_now.cpp **** cout<<factorial(10)<<endl;
15 .loc 1 14 0
16 0004 BE005F37 movl $3628800, %esi
16 00
17 0009 BF000000 movl $_ZSt4cout, %edi
17 00
18 000e E8000000 call _ZNSolsEi
18 00
which means that the compiler has obviously performed a constant folding of (10!) = 3628800
for both cases either using cosnt
or constexpr
.
The compilation is performed via
g++ -O3 -std=c++17 -Wa,-adhln -g main.cpp>main.asm
Despite in most of the cases, many people assume the code now runs faster without any investigation, considering the fact that compilers are clever, I am wondering if there is any real, honest and meaningful optimization benefit behind constexpr
?