lmi
[Top][All Lists]
Advanced

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

Re: [lmi] [lmi-commits] master c01b9b0 02/22: Improve concinnity


From: Vadim Zeitlin
Subject: Re: [lmi] [lmi-commits] master c01b9b0 02/22: Improve concinnity
Date: Wed, 16 Jun 2021 02:09:07 +0200

On Tue, 15 Jun 2021 23:53:14 +0000 Greg Chicares <gchicares@sbcglobal.net> 
wrote:

GC> On 6/7/21 2:37 PM, Vadim Zeitlin wrote:
GC> > On Sun,  6 Jun 2021 21:37:59 -0400 (EDT) Greg Chicares 
<gchicares@sbcglobal.net> wrote:
GC> [...commit trimmed to show only the relevant part...]
GC> > GC> commit c01b9b0ad03a823691fa39e7727a31efe1104f88
GC> > GC>     Improve concinnity
GC> > GC> +    static constexpr double epsilon   
{std::numeric_limits<double>::epsilon()};
GC> > GC> -    static double const epsilon = 
std::numeric_limits<double>::epsilon();
GC> 
GC> I seek a terse alias for a known constant--a modern analogue of:
GC>   #define epsilon DBL_EPSILON
GC> Most of all, I want to choose one strategy for all cases like this,
GC> and apply it without thinking the next time a similar case arises.
GC> 
GC> As the "Improve concinnity" line suggests, I searched for other
GC> places where we'd done something similar, and copied that.
GC> 
GC> But if 'static constexpr' isn't the ideal idiom, then let's choose
GC> another idiom and use it everywhere applicable.

 Yes, absolutely, this is a general principle and should be applied
everywhere, not just here -- I simply missed that there were other
instances of it.

GC> >  I believe that after replacing "const" with "constexpr", "static" has
GC> > become at least redundant and maybe even somewhat harmful, as it forces 
the
GC> > compiler to create the "epsilon" variable in the program, while without it
GC> > it could avoid doing this and just use it at compile time.
GC> 
GC> Let me paraphrase that, so you can say whether I've understood your
GC> line of thought. 'constexpr' alone suggests that the compiler treat
GC> this as a compile-time value, so that it might optimize away the
GC> variable and just use the known constant value directly. However,
GC> 'static' seems to specify that a genuine variable is wanted, which
GC> suggests to the compiler that it shouldn't be optimized away. Have
GC> I understood correctly?

 Yes.

GC> If so, I'd say maybe that's true, but maybe it's not--the Standard
GC> AFAICT doesn't give us enough definite premises to formulate a
GC> syllogism either way.

 I'm pretty sure it does. Using "static" for _local_ variables guarantees
static storage duration, i.e. it must allocate a persistent memory location
for it. This seems like a well-known property of "static" in _this_
context, so I don't know if it's worth looking for the exact section of the
Standard defining this.

GC> And there's always the "as-if" rule, which in
GC> this case seems to mean that it can optimize away a 'static constexpr'
GC> whenever (as in this case) it can deduce that it's all right to do so.

 Probably, but I don't know if we should rely on this when it's easy not to
do it (and, in fact, it's easier not to do it rather than do it). It does
seem to do it in a few simple cases I've tried, but who knows if it can
always do it.

GC> >  So I think it should be just removed here -- but please let me know if 
you
GC> > see some reason to keep it.
GC> 
GC> Here's a counterargument that seems strong to me.
GC> 
GC> 'static constexpr' is what the Standard uses, e.g.:
GC>   [numeric.limits.members/25] (an epsilon, though not a variable)
GC>   static constexpr T epsilon() noexcept;
GC>   [numeric.limits.members/36] (a variable, though not an epsilon)
GC>   static constexpr bool has_infinity;

 Unfortunately, you have fallen victim to a classic blunder of thinking
that "static" means the same thing in C++ programs, instead of having 17.5
different possible meanings (at the last count, averaging over the
different language versions, and only slightly exaggerating). The "static"
here, i.e. for a member variable, is, of course, totally different from
"static" for a local variable, and must be used as both "epsilon" and
"has_infinity" are properties of the type and without "static" they would
become properties of an object, which is definitely not wanted here.

GC> If we were to propose modifying the Standard as follows (e.g.):
GC> 
GC> -  static constexpr bool has_infinity;
GC> +  constexpr bool has_infinity;
GC> 
GC> then what would we realistically expect the Committee to say?
GC> (I believe that proposal would be dismissed out of hand.)

 Yes, but not for the reason you had in mind, I'm afraid.

GC> Do you find that counterargument persuasive?

 Sorry, no. We should definitely use "static" for class members, but this
doesn't mean that we should use it for local variables, and I still think
it should be removed in this case.

 Regards,
VZ

Attachment: pgp5yZTxMirkZ.pgp
Description: PGP signature


reply via email to

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