lundi 19 août 2019

What happens when their's error in constexpr function?

I learnt that constexpr functions are evaluated at compile time. But look at this example:

constexpr int fac(int n)
{
    return (n>1) ? n*fac(n-1) : 1;
}


int main()
{
    const int a = 500000;
    cout << fac(a);
    return 0;
}

Apparently this code would throw an error, but since constexpr functions are evaluated at compiling time, why I see no error when compile and link?

Further on, I disassembled this code, and it turned out this function isn't evaluated but rather called as a normal function:

(gdb) x/10i $pc
=> 0x80007ca <main()>:  sub    $0x8,%rsp
   0x80007ce <main()+4>:        mov    $0x7a11f,%edi
   0x80007d3 <main()+9>:        callq  0x8000823 <fac(int)>
   0x80007d8 <main()+14>:       imul   $0x7a120,%eax,%esi
   0x80007de <main()+20>:       lea    0x20083b(%rip),%rdi        # 0x8201020 <_ZSt4cout@@GLIBCXX_3.4>
   0x80007e5 <main()+27>:       callq  0x80006a0 <_ZNSolsEi@plt>
   0x80007ea <main()+32>:       mov    $0x0,%eax
   0x80007ef <main()+37>:       add    $0x8,%rsp
   0x80007f3 <main()+41>:       retq

However, if I call like fac(5):

constexpr int fac(int n)
{
    return (n>1) ? n*fac(n-1) : 1;
}


int main()
{
    const int a = 5;
    cout << fac(a);
    return 0;
}

The assemble code turned into:

(gdb) x/10i $pc
=> 0x80007ca <main()>:  sub    $0x8,%rsp
   0x80007ce <main()+4>:        mov    $0x78,%esi
   0x80007d3 <main()+9>:        lea    0x200846(%rip),%rdi        # 0x8201020 <_ZSt4cout@@GLIBCXX_3.4>
   0x80007da <main()+16>:       callq  0x80006a0 <_ZNSolsEi@plt>
   0x80007df <main()+21>:       mov    $0x0,%eax
   0x80007e4 <main()+26>:       add    $0x8,%rsp
   0x80007e8 <main()+30>:       retq

The fac function is evaluated at compile time.

Can Anyone explain this?

Compiling command:

g++ -Wall test.cpp -g -O1 -o test

And with g++ version 7.4.0, gdb version 8.1.0

Aucun commentaire:

Enregistrer un commentaire