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 Tue, 19 Feb 2008 17:26:10 GMT


> -----Original Message-----
> From: Martin Sebor [mailto:msebor@gmail.com] On Behalf Of Martin Sebor
> Sent: Monday, February 18, 2008 9:41 PM
> To: dev@stdcxx.apache.org
> Subject: Re: [PATCH] STDCXX-423
> 
> Scott Zhong wrote:
> > Martin,
> >
> >   From the bug description, its saying that in theory integer types
> > might have extra bit padding that contribute to their size but not
their
> > range. What the bit padding will affect is the sizeof() function.
> >
> >    For example: for a 64-bit system, if a strange compiler decides
that
> > int are 6 bytes long instead of 8 bytes long. There would be a 2
byte
> > padding to make int faster to access because it fills the boundary.
In
> > this case, sizeof(int) will return 8, but the actual size of int is
only
> > 6 byte.
> >
> > In my function, compute_byte_size(), it assumes that 1 is stored as
> > 00000000 00000000 ... 0000001.  In the for loop, it shifts that 1
bit to
> > the next bit field.
> >
> > First iteration:  00000000 ... 00000010
> > Second iteration:  00000000 ... 00000100
> > ...
> > ...
> > ...
> > Last iteration: 00000000 00000001 ... 00000000 (this would return 0
> > which is less than the previous value)
> >
> > And so on and so forth.  It then checks the value at those bits to
> > ensure that the value is greater than the previous. This will run
until
> > it is out of boundary of the int type. My function will return 6
bytes
> > in the example that I given instead of 8 bytes that is returned by
> > sizeof().
> 
> Thanks for the explanation, Scott. The patch makes more sense now.
> 
> >
> > 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.

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

> >         byte++;
> >     }
> >     return byte > 0 ? byte : 1;
> > }
> >
> >>From what I read, the only way we can create a type that has bit
padding
> > is by creating a struct with two different size types and only
certain
> > compiler will add the padding.
> 
> Yes, but this is about fundamental types at the language/hardware
> level and unusual word sizes like the one used in the PDP-8 (12
> bits), or on the UNIVAC (36 bits). See for example this article:
>    http://en.wikipedia.org/wiki/Word_%28computing%29
> As I said before, this is mostly of academic interest today since
> virtually all modern hardware employs powers of 2 word sizes.
> 
> Martin
> 
> >
> > In gcc and 32bit x86 system:
> >
> > struct new_int{
> >   int a;
> >   char b;
> > }
> >
> > Int are 4 bytes, char is 1 byte, new_int is padded to 8 byte size
with
> > gcc.
> >
> > -----Original Message-----
> > From: Martin Sebor [mailto:msebor@gmail.com] On Behalf Of Martin
Sebor
> > Sent: Tuesday, February 12, 2008 4:17 PM
> > To: dev@stdcxx.apache.org
> > Subject: Re: [PATCH] STDCXX-423
> >
> > Sorry Scott, I still don't understand what you're trying to do here.
> >
> > The problem noted in STDCXX-423 is pretty much theoretical. AFAIK,
> > stdcxx doesn't build or run on any platform with padding bits. In
> > fact, there may not be any such platforms. Which doesn't mean that
> > there will never be any (as pointed out in the comp.lang.c thread
> > I just updated the issue with), just that coming up with a test
> > case will be tough, as will be testing a patch for the problem.
> >
> > Martin
> >
> > Scott Zhong wrote:
> >> --- LIMITS.cpp  (revision 624452)
> >> +++ LIMITS.cpp  (working copy)
> >> @@ -223,13 +223,27 @@
> >>      return bits;
> >>  }
> >>
> >> +template <class T>
> >> +unsigned compute_byte_size()
> >> +{
> >> +    T max = T (one);
> >> +    unsigned byte = 1;
> >> +    for (int i = 1; T (max * two) > max; max *= two, i++) {
> >> +        if (i > 8 ) {byte++; i = 1; }
> >> +    }
> >> +    return byte;
> >> +}
> >>
> >> +
> >>  // used to compute the size of a pointer to a member function
> >>  struct EmptyStruct { };
> >>
> >>
> >>  // to silence printf() format comaptibility warnings
> >>  #define SIZEOF(T)   unsigned (sizeof (T))
> >> +
> >> +// to not include possible bit padding
> >> +#define CALC_SIZEOF(T)  compute_byte_size<T>()
> >>
> >>
> >>  int main ()
> >> @@ -243,17 +257,17 @@
> >>
> >>  #ifndef _RWSTD_NO_BOOL
> >>      printf ("#define _RWSTD_BOOL_SIZE   %2u /* sizeof (bool)
*/\n",
> >> -            SIZEOF (bool));
> >> +            CALC_SIZEOF (bool));
> >>  #endif   // _RWSTD_NO_BOOL
> >>
> >>      printf ("#define _RWSTD_CHAR_SIZE   %2u /* sizeof (char)
*/\n",
> >> -            SIZEOF (char));
> >> +            CALC_SIZEOF (char));
> >>      printf ("#define _RWSTD_SHRT_SIZE   %2u /* sizeof (short)
*/\n",
> >> -            SIZEOF (short));
> >> +            CALC_SIZEOF (short));
> >>      printf ("#define _RWSTD_INT_SIZE    %2u /* sizeof (int) */\n",
> >> -            SIZEOF (int));
> >> +            CALC_SIZEOF (int));
> >>      printf ("#define _RWSTD_LONG_SIZE   %2u /* sizeof (long)
*/\n",
> >> -            SIZEOF (long));
> >> +            CALC_SIZEOF (long));
> >>
> >>      printf ("#define _RWSTD_FLT_SIZE    %2u /* sizeof (float)
*/\n",
> >>              SIZEOF (float));
> >> @@ -319,7 +333,7 @@
> >>
> >>  #    define LLong long long
> >>
> >> -    printf ("#define _RWSTD_LLONG_SIZE  %2u\n", SIZEOF (LLong));
> >> +    printf ("#define _RWSTD_LLONG_SIZE  %2u\n", CALC_SIZEOF
(LLong));
> >>
> >>      const char llong_name[] = "long long";
> >>
> >> @@ -332,7 +346,7 @@
> >>
> >>  #    define LLong __int64
> >>
> >> -    printf ("#define _RWSTD_LLONG_SIZE  %2u\n", SIZEOF (LLong));
> >> +    printf ("#define _RWSTD_LLONG_SIZE  %2u\n", CALC_SIZEOF
(LLong));
> >>
> >>      const char llong_name[] = "__int64";
> >>
> >> @@ -352,7 +366,7 @@
> >>  #ifndef _RWSTD_NO_WCHAR_T
> >>
> >>      printf ("#define _RWSTD_WCHAR_SIZE  %2u /* sizeof (wchar_t)
> > */\n",
> >> -            SIZEOF (wchar_t));
> >> +            CALC_SIZEOF (wchar_t));
> >>
> >>      const char *suffix = "U";
> >>      if ((wchar_t)~0 < (wchar_t)0)
> >>
> >
> >


Mime
View raw message