stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Scott Zhong" <Scott.Zh...@roguewave.com>
Subject RE: [PATCH] STDCXX-423
Date Tue, 04 Mar 2008 20:40:24 GMT


> -----Original Message-----
> From: Martin Sebor [mailto:sebor@roguewave.com]
> Sent: Wednesday, February 20, 2008 12:26 PM
> To: dev@stdcxx.apache.org
> Subject: Re: [PATCH] STDCXX-423
> 
> Scott Zhong wrote:
> [...]
> >>> As I write this, I realize that the my function,
> > compute_byte_size(),
> >>> can be optimized to shift one bit to the next byte boundary.
> >> I don't think we need to (or should) worry about optimizing config
> >> tests. What we might want to do is use the template parameter in
> >> the signature of the function for non-conforming compilers that
> >> have trouble with these types of things.
> >
> > Sorry I meant to say that its more of a code fix than optimization.
> > Sizeof() returns the number of bytes so the function should check
each
> > byte instead of each bit.
> 
> But not all bits of every byte need to contribute to the value
> representation of the object. IIUC, there can be 4 byte ints
> (i.e., sizeof(int) == 4) with 29 bits for the value, 1 bit for
> the sign, and 2 bits of padding.
> 

I had overlooked that fact, thank you for reminding me.

> >
> >>> template <class T>
> >>> unsigned compute_byte_size()
> >>> {
> >>>     T max = T (one);
> >>>     unsigned byte = 0;
> >>>     for (; T (max * 128) > max; max *= 128) {
> >> FWIW, for signed T the expression T(max * 128) > max has undefined
> >> behavior in the presence of overflow. We've seen at least two (if
> >> not three) compilers exploit this presumably in some aggressive
> >> optimizations (see, for example, STDCXX-482). Since most (all?)
> >> hardware simply wraps around in the presence of overflow we just
> >> need to prevent the compiler optimization here.
> >
> > Would the volatile keyword in front of "max" be sufficient here?
> 
> It might help, but I'm not sure it's guaranteed to. All it usually
> does is make the compiler generate code that reloads the value of
> the object from memory into a register on each access. The stage
> I'm concerned with takes place before code generation based on what
> the compiler can prove about the program. For all signed x, the
> compiler is free to assume that in (x * N) > x, the subexpression
> (x * N) doesn't overflow and thus (x * N) is always guaranteed to
> be greater than x (for N > 0). To prevent it from making such an
> assumption we need to rewrite the expression like so: (x * N) > y
> while initializing x and y to the same value in such a way that
> the compiler cannot prove that (x == y) holds.
> 

Would this suffice?

template <class T>
unsigned compute_byte_size()
{
    T max = T (one);
    T current = T (one);
    unsigned byte = 0;
    for (int I = 1; T (current * 2) > max; current *= 2, max *= 2, i++)
{
        if (i > 8 ) {byte++; i = 1; }
    }
    return byte;
}


> Martin


Mime
View raw message