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 Thu, 06 Mar 2008 16:55:23 GMT
After going through the logic again:

iter #	i	byte	structure

1		1	0		00000001
2		2	0		00000010
3		3	0		00000100
4		4	0		00001000
5		5	0		00010000
6		6	0		00100000
7		7	0		01000000
8		8	0		10000000
9		1	1		00000001 00000000
10		2	1		00000010 00000000
11		3	1		00000100 00000000
12		4	1		00001000 00000000
13		5	1		00010000 00000000
14		6	1		00100000 00000000
15		7	1		01000000 00000000
16		8	1		10000000 00000000
17		1	2		00000001 00000000 00000000

Byte should be initialized to 1.

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

> -----Original Message-----
> From: Martin Sebor [mailto:sebor@roguewave.com]
> Sent: Wednesday, March 05, 2008 5:19 PM
> To: dev@stdcxx.apache.org
> Subject: Re: [PATCH] STDCXX-423
> 
> Scott Zhong wrote:
> >
> >> -----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?
> 
> 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
> >


Mime
View raw message