[math] Warning in math/common_factor_rt.hpp
Hi all, I am getting a warning in math/common_factor_rt.hpp when compiling some code which includes boost headers: cc1plus: warnings being treated as errors /build/toolchain/lin32/boost-1.42.0/include/boost/math/common_factor_rt.hpp: In member function 'char boost::math::detail::gcd_optimal_evaluator<char>::operator()(char, char) const': /build/toolchain/lin32/boost-1.42.0/include/boost/math/common_factor_rt.hpp:329: warning: comparison is always false due to limited range of data type /build/toolchain/lin32/boost-1.42.0/include/boost/math/common_factor_rt.hpp:329: warning: comparison is always false due to limited range of data type Unfortunately that's all the compiler prints - nothing which ties the warning back to any particular piece of my code. None of my code is using the math library directly, though the .cpp being compiled here does include (mostly indirectly) a lot of boost headers. These include multi_index, optional, some MPL and type_traits, range, iterator, and probably others I am not seeing. Any suggestions on how to work around this? Is it possible to disable this warning? I'm using boost 1.42.0 and i686-linux-g++ (GCC) 4.1.2 Thanks, -Gabe
Investigating a bit further, I discovered that we are actually passing -funsigned-char to the compiler. This causes a problem because: common_factor_rt.hpp:329 BOOST_PRIVATE_GCD_SF( char, unsigned char ); // should work even if unsigned This macro expands into: common_factor_rt.hpp:317 #define BOOST_PRIVATE_GCD_SF( St, Ut ) \ template < > struct gcd_optimal_evaluator<St> \ { St operator ()( St a, St b ) const { Ut const a_abs = \ static_cast<Ut>( a < 0 ? -a : +a ), b_abs = static_cast<Ut>( \ b < 0 ? -b : +b ); return static_cast<St>( \ gcd_optimal_evaluator<Ut>()(a_abs, b_abs) ); } } The expression 'a < 0' is always false if 'a' is unsigned, so the compiler issues a warning (if warnings are turned high enough). My impression is that this code should be considered incorrect - making assumptions about the signed-ness of char is not portable. I do not understand why the comment suggests that this "should work". -Gabe
Investigating a bit further, I discovered that we are actually passing -funsigned-char to the compiler. This causes a problem because:
common_factor_rt.hpp:329 BOOST_PRIVATE_GCD_SF( char, unsigned char ); // should work even if unsigned
This macro expands into: common_factor_rt.hpp:317 #define BOOST_PRIVATE_GCD_SF( St, Ut ) \ template < > struct gcd_optimal_evaluator<St> \ { St operator ()( St a, St b ) const { Ut const a_abs = \ static_cast<Ut>( a < 0 ? -a : +a ), b_abs = static_cast<Ut>( \ b < 0 ? -b : +b ); return static_cast<St>( \ gcd_optimal_evaluator<Ut>()(a_abs, b_abs) ); } }
The expression 'a < 0' is always false if 'a' is unsigned, so the compiler issues a warning (if warnings are turned high enough).
My impression is that this code should be considered incorrect - making assumptions about the signed-ness of char is not portable. I do not understand why the comment suggests that this "should work".
Actually I think in this case the code will work correctly, but in any case this patch should fix things: https://svn.boost.org/trac/boost/changeset/63496/trunk/boost/math/common_fac... HTH, John.
Hi John, Thanks for your reply. My reading of the code is that it does indeed work correctly if char is unsigned - it just ends up making some comparisons which resolve to compile-time constants, which generates warnings if GCC is given the right flags. The patch you linked looks like it should fix the problem, though I have not tested it. In the short term I am looking into removing the -funsigned-char flag from our builds, since AFAICT it is not necessary. Thanks again, -Gabe
participants (2)
-
Gabriel Redner
-
John Maddock