Scott Zhong wrote:

-----Original Message-----
From: Martin Sebor [mailto:[EMAIL PROTECTED]
Sent: Wednesday, February 20, 2008 12:26 PM
To: [email protected]
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?

This doesn't seem correct, not just because of the typo but because
it returns 3 for T = int (assuming one == 1). Even if it was correct
I'm not sure a smart optimizer couldn't make some assumptions about
the dependency between current and max (they are both modified using
exactly the same expression) that would cause the code to misbehave.

Martin


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


Reply via email to