stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: [PATCH] STDCXX-423
Date Wed, 20 Feb 2008 19:26:13 GMT
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.

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

Martin


Mime
View raw message