changeset 7534:ef755c763b62

avoid more "comparison is always false due to limited range of data type" warnings from GCC
author John W. Eaton <jwe@octave.org>
date Tue, 26 Feb 2008 17:37:37 -0500
parents ff52243af934
children bda16af4fd2f
files liboctave/oct-inttypes.h src/ChangeLog src/ov-base-int.cc
diffstat 3 files changed, 87 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/oct-inttypes.h	Tue Feb 26 05:28:59 2008 -0500
+++ b/liboctave/oct-inttypes.h	Tue Feb 26 17:37:37 2008 -0500
@@ -199,8 +199,9 @@
                            OCTAVE_INT_MIN_VAL2 (T1, T2), \
                            OCTAVE_INT_MAX_VAL2 (T1, T2))
 
-// By using these classes/functions we avoid warnings from GCC about
-// comparisons always being false due to limited range of data type.
+// We have all the machinery below (octave_int_helper) to avoid a few
+// warnings from GCC about comparisons always false due to limited
+// range of data types.  Ugh.  The cure may be worse than the disease.
 
 // FIXME -- it would be nice to nest the helper class inside the
 // octave_int class, but I don't see the magic for that at the moment.
--- a/src/ChangeLog	Tue Feb 26 05:28:59 2008 -0500
+++ b/src/ChangeLog	Tue Feb 26 17:37:37 2008 -0500
@@ -1,5 +1,10 @@
 2008-02-26  John W. Eaton  <jwe@octave.org>
 
+	* ov-base-int.cc (octave_base_int_helper,
+	octave_base_int_helper_traits): New templates and specializations.
+	(octave_base_int_matrix<T>::convert_to_str_internal,
+	octave_base_int_matrix<T>::convert_to_str_internal): Use them.
+
 	* DLD-FUNCTIONS/rand.cc (do_rand): Pass name of calling function
 	to octave_rand::state.
 
--- a/src/ov-base-int.cc	Tue Feb 26 05:28:59 2008 -0500
+++ b/src/ov-base-int.cc	Tue Feb 26 17:37:37 2008 -0500
@@ -55,6 +55,67 @@
 #include "ls-utils.h"
 #include "ls-hdf5.h"
 
+// We have all the machinery below (octave_base_int_helper and
+// octave_base_int_helper_traits) to avoid a few warnings from GCC
+// about comparisons always false due to limited range of data types.
+// Ugh.  The cure may be worse than the disease.
+
+template <class T, bool is_signed = true, bool can_be_too_big = true>
+struct octave_base_int_helper
+{
+  static bool
+  char_value_out_of_range (T val) { return val < 0 || val > UCHAR_MAX; }
+};
+
+template <class T>
+struct octave_base_int_helper<T, false, false>
+{
+  static bool char_value_out_of_range (T) { return true; }
+};
+
+template <class T>
+struct octave_base_int_helper<T, false, true>
+{
+  static bool char_value_out_of_range (T val) { return val > UCHAR_MAX; }
+};
+
+template <class T>
+struct octave_base_int_helper<T, true, false>
+{
+  static bool char_value_out_of_range (T val) { return val < 0; }
+};
+
+// For all types other than char, signed char, and unsigned char, we
+// assume that the upper limit for the range of allowable values is
+// larger than the range for unsigned char.  If that's not true, we
+// are still OK, but will see the warnings again for any other types
+// that do not meet this assumption.
+
+template <class T>
+struct octave_base_int_helper_traits
+{
+  static const bool can_be_larger_than_uchar_max = true;
+};
+
+template <>
+struct octave_base_int_helper_traits<char>
+{
+  static const bool can_be_larger_than_uchar_max = false;
+};
+
+template <>
+struct octave_base_int_helper_traits<signed char>
+{
+  static const bool can_be_larger_than_uchar_max = false;
+};
+
+template <>
+struct octave_base_int_helper_traits<unsigned char>
+{
+  static const bool can_be_larger_than_uchar_max = false;
+};
+
+
 template <class T>
 octave_base_value *
 octave_base_int_matrix<T>::try_narrowing_conversion (void)
@@ -85,10 +146,16 @@
 
       typename T::elt_type tmp = this->matrix(i);
 
-      typename T::elt_type::val_type ival = tmp.value ();
+      typedef typename T::elt_type::val_type val_type;
+
+      val_type ival = tmp.value ();
 
-      
-      if (ival < 0 || ival > UCHAR_MAX)
+      static const bool is_signed = std::numeric_limits<val_type>::is_signed;
+      static const bool can_be_larger_than_uchar_max
+	= octave_base_int_helper_traits<val_type>::can_be_larger_than_uchar_max;
+
+      if (octave_base_int_helper<val_type, is_signed,
+	  can_be_larger_than_uchar_max>::char_value_out_of_range (ival))
 	{
 	  // FIXME -- is there something better we could do?
 
@@ -378,9 +445,16 @@
 
   T tmp = this->scalar;
 
-  typename T::val_type ival = tmp.value ();
+  typedef typename T::val_type val_type;
+
+  val_type ival = tmp.value ();
 
-  if (ival < 0 || ival > UCHAR_MAX)
+  static const bool is_signed = std::numeric_limits<val_type>::is_signed;
+  static const bool can_be_larger_than_uchar_max
+    = octave_base_int_helper_traits<val_type>::can_be_larger_than_uchar_max;
+
+  if (octave_base_int_helper<val_type, is_signed,
+      can_be_larger_than_uchar_max>::char_value_out_of_range (ival))
     {
       // FIXME -- is there something better we could do?