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 Thu, 13 Mar 2008 20:44:09 GMT
Scott Zhong wrote:
>> -----Original Message-----
>> From: Martin Sebor [mailto:sebor@roguewave.com]
>> Sent: Thursday, March 13, 2008 12:32 PM
>> To: dev@stdcxx.apache.org
>> Subject: RE: [PATCH] STDCXX-423
>>
>>
>> Okay, so this function seems to correctly compute the number of bytes
>> in the value representation of the object. Remind me, where do we need
>> it in the rest of LIMITS.cpp again? I.e., what does the patch look
>> like?
>>
>> Thanks
>> Martin
>>
> 
> The patch looks like the following; it replaces SIZEOF macro on int
> types with CALC_SIZEOF macro. The CALC_SIZEOF macro expends to
> compute_byte_size function.

That's what I thought. I'm afraid I don't think this is correct.
The value of a sizeof expression must be the size of the operand
expressed as (n X CHAR_BIT), and that's what the test computes.

The problem noted in the issue is not with the sizeof operator or
the _RWSTD_XXX_SIZE macros but rather with the exact-width integer
types such as int32_t, and the assumption made in the test that
integer types for which sizeof returns 1, 2, 4, or 8, respectively,
have no padding bits.

For example, the code here:
http://fisheye6.cenqua.com/browse/stdcxx/trunk/etc/config/src/LIMITS.cpp?r=611451#l531

531    if (32 == char_bits * sizeof (int) && !(bits & 4)) {
532        bits |= 4;
533        printf ("#define _RWSTD_INT32_T  int\n");
534 	   printf ("#define _RWSTD_UINT32_T unsigned int\n");
535    }

will incorrectly define int32_t to int when sizeof(int) == 4 holds even
when int has 1 or more padding bits.

I assume you're familiar with the C99 spec for exact-width integer types
but just for reference:

   7.18.1.1  Exact-width integer types
   -1- The typedef name intN_t designates a signed integer type with
       width N, no padding bits, and a two’s complement representation.
       Thus, int8_t denotes a signed integer type with a width of
       exactly 8 bits.
   -2- The typedef name uintN_t designates an unsigned integer type
       with width N. Thus, uint24_t denotes an unsigned integer type
       with a width of exactly 24 bits.
   -3- These types are optional. However, if an implementation provides
       integer types with widths of 8, 16, 32, or 64 bits, it shall
       define the corresponding typedef names.

What we need to do to solve the exceedingly hypothetical problem noted
in STDCXX-423 is compute the number of bits in the value representation
of integer types with widths of 8, 16, 32, and 64 bits, compare the
results with number of bits in their object representation and only
if the two match define the corresponding exact-width typedefs.

Martin

> 
> --- 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);
> +    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;
> +}
> 
> + 
>  // 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