lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Don't initialize constexpr variable with std::ldexp()


From: Vadim Zeitlin
Subject: Re: [lmi] Don't initialize constexpr variable with std::ldexp()
Date: Mon, 24 Apr 2017 18:16:32 +0200

On Mon, 24 Apr 2017 15:25:48 +0000 Greg Chicares <address@hidden> wrote:

GC> With this patch, does the 'bourn_cast_test.cpp' unit test compile and
GC> report zero errors with these other two compilers?

 Yes, the test passes with both gcc and clang (and sorry, I meant to say
this in my previous message but after rereading it I see that I forgot to
include it).

GC> >  Notice that I didn't change the "static" keyword even though I'm not
GC> > really sure if it's appropriate to use it here and, moreover, if I'm quite
GC> > sure that it's not useful to use it with "constexpr" in the
GC> > is_twos_complement declaration just below. Maybe this should be addressed
GC> > too...
GC> 
GC> With this patch, I should think that 'static' is beneficial.
GC> 
GC>   const From limit = std::ldexp(From(1), to_traits::digits);
GC> 
GC> This is what we used to call an 'auto' variable. Notionally, each time the
GC> containing function is called, the compiler allocates storage for it, calls
GC> ldexp(), and frees the storage upon leaving the scope. A compiler can do
GC> something smarter than that, but we aren't giving it any hint that it 
should.
GC> 
GC>   static const From limit = std::ldexp(From(1), to_traits::digits);
GC> 
GC> Using storage class 'static' instructs the compiler to initialize 'limit'
GC> once and only once, and preserve that value across multiple calls to the
GC> containing function. That's what we want, but without 'static' we can't be
GC> sure that's what we get.

 This is true, but I expect the call to ldexp() to be very fast even if
it's not evaluated at compile-time -- which should be the case with gcc.
OTOH static variables must be MT-safe in C++11 and so using it here must
involve at least an atomic variable access (or maybe even a mutex
lock/unlock?), which could well be more expensive.

 In practice, I don't see any noticeable difference in the speed measures,
as performed by the test, when removing "static" from this line with clang.
And with gcc the code is identical in both cases as it evaluates ldexp() at
compile-time anyhow, of course.


GC> However...
GC> 
GC>   static constexpr From limit = std::ldexp(From(1), to_traits::digits);
GC> 
GC> In a dialect that includes P0533R0 [cited above], 'constexpr' is legal here,
GC> and the question arises whether we should use 'static' as well. 'constexpr'
GC> already requires that the value be computed at compile time (and used every
GC> time the function is called), which is the reason we used 'static' above.
GC> Thus, there's no reason to use 'static' in addition to 'constexpr' here.

 Yes.

GC> But is there any reason not to use 'static' here?

 I think there is, and this reason is just that it's unnecessary, i.e.
removing it doesn't affect the program behaviour in any way, but just makes
it one word shorter, which is always a worthwhile optimization.

GC> Is that your reasoning for suggesting s/static constexpr/static/g throughout
GC> this header?

 I think the above is just a typo but, just to be sure, this is not what
I'm suggesting: I'm rather suggesting "s/static constexpr/constexpr/g".

 Regards,
VZ


reply via email to

[Prev in Thread] Current Thread [Next in Thread]