dimanche 18 février 2018

A meaningful advantage of constexpr

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?

Aucun commentaire:

Enregistrer un commentaire