On Thu, Mar 15, 2012 at 01:39:18AM +0000, Stuart Henderson wrote:
> $ c++ -pedantic -c a.c
> In file included from /usr/include/g++/memory:60,
>                  from /usr/include/g++/string:48,
>                  from a.c:1:
> /usr/include/g++/limits: In static member function 'static char 
> std::numeric_limits<char>::min()':
> /usr/include/g++/limits:375: warning: overflow in implicit constant conversion
> /usr/include/g++/limits: In static member function 'static wchar_t 
> std::numeric_limits<wchar_t>::max()':
> /usr/include/g++/limits:530: warning: overflow in implicit constant conversion

It's not even fixed in gcc 4.6.2, not fully anyways.

The following patch might work, it really needs to be read by people who
understand this

- the max warning comes from gcc 4.6.2, this one should be fine.
- the min warning affects the specialization for char, but char is
either signed char or unsigned char, so we can borrow the specializations
from those types.  Preferably directly, to avoid duplication. Obviously,
gcc will whine at having definitions in the wrong order, so it's possible
to reorder things to avoid that as well.

Please test. I've "fixed" limits directly, then backfitted the patch to
the right src file (been a while since I hacked on this), and I hope it's
correct.


Index: std_limits.h
===================================================================
RCS file: /cvs/src/gnu/gcc/libstdc++-v3/include/std/std_limits.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 std_limits.h
--- std_limits.h        15 Oct 2009 17:11:32 -0000      1.1.1.1
+++ std_limits.h        15 Mar 2012 10:16:04 -0000
@@ -137,7 +137,9 @@
   (__glibcxx_signed (T) ? (T)1 << __glibcxx_digits (T) : (T)0)
 
 #define __glibcxx_max(T) \
-  (__glibcxx_signed (T) ? ((T)1 << __glibcxx_digits (T)) - 1 : ~(T)0)
+  (__glibcxx_signed (T) ? \
+      (((((T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0)
+
 
 #define __glibcxx_digits(T) \
   (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T))
@@ -365,57 +367,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       static const float_round_style round_style = round_toward_zero;
     };
 
-  /// numeric_limits<char> specialization.
-  template<>
-    struct numeric_limits<char>
-    {
-      static const bool is_specialized = true;
-
-      static char min() throw()
-      { return __glibcxx_min(char); }
-      static char max() throw()
-      { return __glibcxx_max(char); }
-
-      static const int digits = __glibcxx_digits (char);
-      static const int digits10 = __glibcxx_digits10 (char);
-      static const bool is_signed = __glibcxx_signed (char);
-      static const bool is_integer = true;
-      static const bool is_exact = true;
-      static const int radix = 2;
-      static char epsilon() throw()
-      { return 0; }
-      static char round_error() throw()
-      { return 0; }
-
-      static const int min_exponent = 0;
-      static const int min_exponent10 = 0;
-      static const int max_exponent = 0;
-      static const int max_exponent10 = 0;
-
-      static const bool has_infinity = false;
-      static const bool has_quiet_NaN = false;
-      static const bool has_signaling_NaN = false;
-      static const float_denorm_style has_denorm = denorm_absent;
-      static const bool has_denorm_loss = false;
-
-      static char infinity() throw()
-      { return char(); }
-      static char quiet_NaN() throw()
-      { return char(); }
-      static char signaling_NaN() throw()
-      { return char(); }
-      static char denorm_min() throw()
-      { return static_cast<char>(0); }
-
-      static const bool is_iec559 = false;
-      static const bool is_bounded = true;
-      static const bool is_modulo = true;
-
-      static const bool traps = __glibcxx_integral_traps;
-      static const bool tinyness_before = false;
-      static const float_round_style round_style = round_toward_zero;
-    };
-
   /// numeric_limits<signed char> specialization.
   template<>
     struct numeric_limits<signed char>
@@ -508,6 +459,61 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       { return static_cast<unsigned char>(0); }
       static unsigned char denorm_min() throw()
       { return static_cast<unsigned char>(0); }
+
+      static const bool is_iec559 = false;
+      static const bool is_bounded = true;
+      static const bool is_modulo = true;
+
+      static const bool traps = __glibcxx_integral_traps;
+      static const bool tinyness_before = false;
+      static const float_round_style round_style = round_toward_zero;
+    };
+
+  /// numeric_limits<char> specialization.
+  template<>
+    struct numeric_limits<char>
+    {
+      static const bool is_specialized = true;
+
+      static char min() throw()
+      { return __glibcxx_signed(char) ? 
+           numeric_limits<signed char>::min() :
+           numeric_limits<unsigned char>::min(); }
+      static char max() throw()
+      { return __glibcxx_signed(char) ? 
+           numeric_limits<signed char>::max() :
+           numeric_limits<unsigned char>::max(); }
+
+      static const int digits = __glibcxx_digits (char);
+      static const int digits10 = __glibcxx_digits10 (char);
+      static const bool is_signed = __glibcxx_signed (char);
+      static const bool is_integer = true;
+      static const bool is_exact = true;
+      static const int radix = 2;
+      static char epsilon() throw()
+      { return 0; }
+      static char round_error() throw()
+      { return 0; }
+
+      static const int min_exponent = 0;
+      static const int min_exponent10 = 0;
+      static const int max_exponent = 0;
+      static const int max_exponent10 = 0;
+
+      static const bool has_infinity = false;
+      static const bool has_quiet_NaN = false;
+      static const bool has_signaling_NaN = false;
+      static const float_denorm_style has_denorm = denorm_absent;
+      static const bool has_denorm_loss = false;
+
+      static char infinity() throw()
+      { return char(); }
+      static char quiet_NaN() throw()
+      { return char(); }
+      static char signaling_NaN() throw()
+      { return char(); }
+      static char denorm_min() throw()
+      { return static_cast<char>(0); }
 
       static const bool is_iec559 = false;
       static const bool is_bounded = true;

Reply via email to