You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@stdcxx.apache.org by Scott Zhong <Sc...@roguewave.com> on 2008/03/19 22:20:08 UTC

[PATCH] STDCXX-423 LIMITS.cpp assumes integers with no padding bits

Index: LIMITS.cpp
===================================================================
--- LIMITS.cpp  (revision 638996)
+++ LIMITS.cpp  (working copy)
@@ -223,7 +223,19 @@
     return bits;
 }
 
+template <class T>
+unsigned compute_type_bits()
+{
+    T max = T (one);
+    T current = T(one);
+    int bits = 1;
 
+    for (; T (current * 2) > max; current *=2, max *= 2, bits++) { }
+
+    return bits;
+}
+
+
 // used to compute the size of a pointer to a member function
 struct EmptyStruct { };
 
@@ -397,6 +409,12 @@
     // 1 for a 16-bit integer, etc)
     int width_bits = 0;
 
+    // store exact bit size of each type
+    int ushort_bits = compute_type_bits<unsigned short> ();
+    int uint_bits = compute_type_bits<unsigned int> ();
+    int ulong_bits = compute_type_bits<unsigned long> ();
+    int ullong_bits = compute_type_bits<unsigned LLong> ();
+
 #define PRINT_SPECIFIC(width, least, type)
\
     do {
\
         /* avoid warnings about expression being constant */
\
@@ -430,59 +448,59 @@
         PRINT_SPECIFIC (64, "", "char");
     }
 
-    if (16 == char_bits * sizeof (short) && !(width_bits & 2)) {
+    if (16 == ushort_bits && !(width_bits & 2)) {
         width_bits |= 2;
         PRINT_SPECIFIC (16, "", "short");
     }
-    else if (32 == char_bits * sizeof (short) && !(width_bits & 4)) {
+    else if (32 == ushort_bits && !(width_bits & 4)) {
         width_bits |= 4;
         PRINT_SPECIFIC (32, "", "short");
     }
-    else if (64 == char_bits * sizeof (short) && !(width_bits & 8)) {
+    else if (64 == ushort_bits && !(width_bits & 8)) {
         width_bits |= 8;
         PRINT_SPECIFIC (64, "", "short");
     }
-    else if (128 == char_bits * sizeof (short) && !(width_bits & 16)) {
+    else if (128 == ushort_bits && !(width_bits & 16)) {
         width_bits |= 16;
         PRINT_SPECIFIC (128, "", "short");
     }
 
-    if (32 == char_bits * sizeof (int) && !(width_bits & 4)) {
+    if (32 == uint_bits && !(width_bits & 4)) {
         width_bits |= 4;
         PRINT_SPECIFIC (32, "", "int");
     }
-    else if (64 == char_bits * sizeof (int) && !(width_bits & 8)) {
+    else if (64 == uint_bits && !(width_bits & 8)) {
         width_bits |= 8;
         PRINT_SPECIFIC (64, "", "int");
     }
-    else if (128 == char_bits * sizeof (int) && !(width_bits & 16)) {
+    else if (128 == uint_bits && !(width_bits & 16)) {
         width_bits |= 16;
         PRINT_SPECIFIC (128, "", "int");
     }
 
-    if (32 == char_bits * sizeof (long) && !(width_bits & 4)) {
+    if (32 == ulong_bits && !(width_bits & 4)) {
         width_bits |= 4;
         PRINT_SPECIFIC (32, "", "long");
     }
-    else if (64 == char_bits * sizeof (long) && !(width_bits & 8)) {
+    else if (64 == ulong_bits && !(width_bits & 8)) {
         width_bits |= 8;
         PRINT_SPECIFIC (64, "", "long");
     }
-    else if (128 == char_bits * sizeof (long) && !(width_bits & 16)) {
+    else if (128 == ulong_bits && !(width_bits & 16)) {
         width_bits |= 16;
         PRINT_SPECIFIC (128, "", "long");
     }

-    if (32 == char_bits * sizeof (LLong) && !(width_bits & 4)) {
+    if (32 == ullong_bits && !(width_bits & 4)) {
         width_bits |= 4;
         PRINT_SPECIFIC (32, "", llong_name);
     }
-    else if (64 == char_bits * sizeof (LLong) && !(width_bits & 8)) {
+    else if (64 == ullong_bits && !(width_bits & 8)) {
         width_bits |= 8;
         PRINT_SPECIFIC (64, "", llong_name);
 
     }
-    else if (128 == char_bits * sizeof (LLong) && !(width_bits & 16)) {
+    else if (128 == ullong_bits && !(width_bits & 16)) {
         width_bits |= 16;
         PRINT_SPECIFIC (128, "", llong_name);
     }

RE: [PATCH] STDCXX-423 LIMITS.cpp assumes integers with no padding bits

Posted by Scott Zhong <Sc...@roguewave.com>.

> -----Original Message-----
> From: Martin Sebor [mailto:msebor@gmail.com] On Behalf Of Martin Sebor
> Sent: Saturday, March 22, 2008 4:47 PM
> To: dev@stdcxx.apache.org
> Subject: Re: [PATCH] STDCXX-423 LIMITS.cpp assumes integers with no
> padding bits
> 
> Sorry Scott, I'm still not sure this is completely correct.
> 
> According to 7.18.1.1 of C99, "The typedef name intN_t designates
> a signed integer type with width N, no padding bits, and a two's
> complement representation."
> 
> Can you point me to the part of the patch that checks that each
> of the exact-width types has no padding bits and that it uses
> a two's complement representation?
> 
> A few more comments are inline...
> 
> Scott Zhong wrote:
> > Index: LIMITS.cpp
> > ===================================================================
> > --- LIMITS.cpp  (revision 638996)
> > +++ LIMITS.cpp  (working copy)
> > @@ -223,7 +223,19 @@
> >      return bits;
> >  }
> >
> > +template <class T>
> > +unsigned compute_type_bits()
> > +{
> > +    T max = T (one);
> > +    T current = T(one);
> > +    int bits = 1;
> >
> > +    for (; T (current * 2) > max; current *=2, max *= 2, bits++) {
}
> > +
> > +    return bits;
> > +}
> 
> This function computes the number of bits in the value representation
> of the type T. We also need to compute the number of bits in the
object
> representation of the type (i.e., sizeof(T) * CHAR_BIT). Only if the
> two match, and when (no_twos_complement == 0) holds can we define
> the exact-width types.
> 
> > +
> > +
> >  // used to compute the size of a pointer to a member function
> >  struct EmptyStruct { };
> >
> > @@ -397,6 +409,12 @@
> >      // 1 for a 16-bit integer, etc)
> >      int width_bits = 0;
> >
> > +    // store exact bit size of each type
> > +    int ushort_bits = compute_type_bits<unsigned short> ();
> > +    int uint_bits = compute_type_bits<unsigned int> ();
> > +    int ulong_bits = compute_type_bits<unsigned long> ();
> > +    int ullong_bits = compute_type_bits<unsigned LLong> ();
> 
> The last line needs to be guarded in case long long is not
> recognized as a type (e.g., EDG eccp in strict mode).
> 
> Martin
> 

Martin, the macro LLong already takes care of this.

Re: [PATCH] STDCXX-423 LIMITS.cpp assumes integers with no padding bits

Posted by Martin Sebor <se...@roguewave.com>.
Sorry Scott, I'm still not sure this is completely correct.

According to 7.18.1.1 of C99, "The typedef name intN_t designates
a signed integer type with width N, no padding bits, and a two's
complement representation."

Can you point me to the part of the patch that checks that each
of the exact-width types has no padding bits and that it uses
a two's complement representation?

A few more comments are inline...

Scott Zhong wrote:
> Index: LIMITS.cpp
> ===================================================================
> --- LIMITS.cpp  (revision 638996)
> +++ LIMITS.cpp  (working copy)
> @@ -223,7 +223,19 @@
>      return bits;
>  }
>  
> +template <class T>
> +unsigned compute_type_bits()
> +{
> +    T max = T (one);
> +    T current = T(one);
> +    int bits = 1;
>  
> +    for (; T (current * 2) > max; current *=2, max *= 2, bits++) { }
> +
> +    return bits;
> +}

This function computes the number of bits in the value representation
of the type T. We also need to compute the number of bits in the object
representation of the type (i.e., sizeof(T) * CHAR_BIT). Only if the
two match, and when (no_twos_complement == 0) holds can we define
the exact-width types.

> +
> +
>  // used to compute the size of a pointer to a member function
>  struct EmptyStruct { };
>  
> @@ -397,6 +409,12 @@
>      // 1 for a 16-bit integer, etc)
>      int width_bits = 0;
>  
> +    // store exact bit size of each type
> +    int ushort_bits = compute_type_bits<unsigned short> ();
> +    int uint_bits = compute_type_bits<unsigned int> ();
> +    int ulong_bits = compute_type_bits<unsigned long> ();
> +    int ullong_bits = compute_type_bits<unsigned LLong> ();

The last line needs to be guarded in case long long is not
recognized as a type (e.g., EDG eccp in strict mode).

Martin

> +
>  #define PRINT_SPECIFIC(width, least, type)
> \
>      do {
> \
>          /* avoid warnings about expression being constant */
> \
> @@ -430,59 +448,59 @@
>          PRINT_SPECIFIC (64, "", "char");
>      }
>  
> -    if (16 == char_bits * sizeof (short) && !(width_bits & 2)) {
> +    if (16 == ushort_bits && !(width_bits & 2)) {
>          width_bits |= 2;
>          PRINT_SPECIFIC (16, "", "short");
>      }
> -    else if (32 == char_bits * sizeof (short) && !(width_bits & 4)) {
> +    else if (32 == ushort_bits && !(width_bits & 4)) {
>          width_bits |= 4;
>          PRINT_SPECIFIC (32, "", "short");
>      }
> -    else if (64 == char_bits * sizeof (short) && !(width_bits & 8)) {
> +    else if (64 == ushort_bits && !(width_bits & 8)) {
>          width_bits |= 8;
>          PRINT_SPECIFIC (64, "", "short");
>      }
> -    else if (128 == char_bits * sizeof (short) && !(width_bits & 16)) {
> +    else if (128 == ushort_bits && !(width_bits & 16)) {
>          width_bits |= 16;
>          PRINT_SPECIFIC (128, "", "short");
>      }
>  
> -    if (32 == char_bits * sizeof (int) && !(width_bits & 4)) {
> +    if (32 == uint_bits && !(width_bits & 4)) {
>          width_bits |= 4;
>          PRINT_SPECIFIC (32, "", "int");
>      }
> -    else if (64 == char_bits * sizeof (int) && !(width_bits & 8)) {
> +    else if (64 == uint_bits && !(width_bits & 8)) {
>          width_bits |= 8;
>          PRINT_SPECIFIC (64, "", "int");
>      }
> -    else if (128 == char_bits * sizeof (int) && !(width_bits & 16)) {
> +    else if (128 == uint_bits && !(width_bits & 16)) {
>          width_bits |= 16;
>          PRINT_SPECIFIC (128, "", "int");
>      }
>  
> -    if (32 == char_bits * sizeof (long) && !(width_bits & 4)) {
> +    if (32 == ulong_bits && !(width_bits & 4)) {
>          width_bits |= 4;
>          PRINT_SPECIFIC (32, "", "long");
>      }
> -    else if (64 == char_bits * sizeof (long) && !(width_bits & 8)) {
> +    else if (64 == ulong_bits && !(width_bits & 8)) {
>          width_bits |= 8;
>          PRINT_SPECIFIC (64, "", "long");
>      }
> -    else if (128 == char_bits * sizeof (long) && !(width_bits & 16)) {
> +    else if (128 == ulong_bits && !(width_bits & 16)) {
>          width_bits |= 16;
>          PRINT_SPECIFIC (128, "", "long");
>      }
> 
> -    if (32 == char_bits * sizeof (LLong) && !(width_bits & 4)) {
> +    if (32 == ullong_bits && !(width_bits & 4)) {
>          width_bits |= 4;
>          PRINT_SPECIFIC (32, "", llong_name);
>      }
> -    else if (64 == char_bits * sizeof (LLong) && !(width_bits & 8)) {
> +    else if (64 == ullong_bits && !(width_bits & 8)) {
>          width_bits |= 8;
>          PRINT_SPECIFIC (64, "", llong_name);
>  
>      }
> -    else if (128 == char_bits * sizeof (LLong) && !(width_bits & 16)) {
> +    else if (128 == ullong_bits && !(width_bits & 16)) {
>          width_bits |= 16;
>          PRINT_SPECIFIC (128, "", llong_name);
>      }
>