> -----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?
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