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