Mercurial > hg > octave-lyh
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 +++ b/liboctave/oct-inttypes.h @@ -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 +++ b/src/ChangeLog @@ -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 +++ b/src/ov-base-int.cc @@ -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?