简体   繁体   中英

constexpr versus template, pow function

I am experimenting new feature of the c++11, constexpr especially. If I want to code a pow with template I will simply do:

//pow
template<class T, std::size_t n>
struct helper_pow{
    inline static T pow(T const& a){
        return a*helper_pow<T,n-1>::pow(a);
    }
};

//final specialization pow 
template<class T>
struct helper_pow<T,0>{
    inline static T pow(T const& a){
        return 1;
    }
};

Now if I call my function into my code simply by:

pow<double,5>(a) // where a is double

the corresponding assembly will be (gcc 4.8.0, -O2):

   movapd  %xmm0, %xmm1
    movsd   %xmm0, 24(%rsp)
    mulsd   %xmm0, %xmm1
    movq    %rbx, %rdi
    mulsd   %xmm0, %xmm1
    mulsd   %xmm0, %xmm1
    mulsd   %xmm0, %xmm1

Fine the code is inline.

If know I am looking the constexpr version, I have

template <class T>
inline constexpr T pow(T const& x, std::size_t n){
    return n>0 ? x*pow(x,n-1):1;
} 

The corresponding assembly is now:

    movsd   24(%rsp), %xmm2
    leaq    24(%rsp), %rdi
    movl    $4, %esi
    movsd   %xmm2, 8(%rsp)
    call    __Z3powIdET_RS0_m

where the function __Z#powIdET_RS0_m seems define by

LCFI1:
    mulsd   %xmm1, %xmm0
    movapd  %xmm0, %xmm2
    mulsd   %xmm1, %xmm2
    mulsd   %xmm2, %xmm1
    movapd  %xmm1, %xmm0
    ret

So do you have any idea why with constexpr the function is not inline and consider as "an external" function ? Does it exist a way to force the inline of a constexpr function ? Best.

inline is nothing more than a hint for the compiler. It can do whatever it prefers. It exists compiler specific stuff like pragmas and __declspec to force on or off the inlining on a function.

May be the non const lvalue reference of the constexpr version interfers. You should just pass by value to a pow anyway.

It is not an error for a particular instantiation of a constexpr function template to not be really constexpr, as long as you don't attempt to use it in a context that requires a constant expression. Maybe your instantiated template is not constexpr.

To find out, do this:

constexpr double powtest = pow(2.0, 5);

If the compiler complains, you know there's something wrong.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM