Scott Zhong wrote:
-----Original Message-----
From: Martin Sebor [mailto:[EMAIL PROTECTED]
Sent: Thursday, March 13, 2008 12:32 PM
To: [email protected]
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)




Reply via email to