From: Vadim Zeitlin Date: Wed, 27 Oct 2010 20:23:55 +0000 (+0000) Subject: Fix warnings about signed/unsigned comparisons inside wxMax() and friends. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/2a0ca9dbafcdb76d95bca0319d29699ac1fefc64?ds=inline Fix warnings about signed/unsigned comparisons inside wxMax() and friends. wxMax, wxMin and wxClip work correctly when called with a mix of signed and unsigned arguments but give warnings about comparing them when compiled with g++. Cast both arguments to the result type, which is defined consistently with standard C rules for implicit promotion, before comparing them to avoid this. Also add more tests to check that using these functions in this case doesn't provoke warnings. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65933 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/utils.h b/include/wx/utils.h index 96d1a9acd1..6f7cb56dde 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -63,21 +63,35 @@ template inline typename wxImplicitConversionType::value wxMax(T1 a, T2 b) { - return (a > b) ? a : b; + typedef typename wxImplicitConversionType::value ResultType; + + // Cast both operands to the same type before comparing them to avoid + // warnings about signed/unsigned comparisons from some compilers: + return static_cast(a) > static_cast(b) ? a : b; } template inline typename wxImplicitConversionType::value wxMin(T1 a, T2 b) { - return (a < b) ? a : b; + typedef typename wxImplicitConversionType::value ResultType; + + return static_cast(a) < static_cast(b) ? a : b; } template inline typename wxImplicitConversionType3::value wxClip(T1 a, T2 b, T3 c) { - return (a < b) ? b : ((a > c) ? c : a); + typedef typename wxImplicitConversionType3::value ResultType; + + if ( static_cast(a) < static_cast(b) ) + return b; + + if ( static_cast(a) > static_cast(c) ) + return c; + + return a; } // ---------------------------------------------------------------------------- diff --git a/tests/misc/metatest.cpp b/tests/misc/metatest.cpp index ed1d4c388e..9072c70334 100644 --- a/tests/misc/metatest.cpp +++ b/tests/misc/metatest.cpp @@ -36,11 +36,13 @@ private: CPPUNIT_TEST( IsPod ); CPPUNIT_TEST( IsMovable ); CPPUNIT_TEST( ImplicitConversion ); + CPPUNIT_TEST( MinMax ); CPPUNIT_TEST_SUITE_END(); void IsPod(); void IsMovable(); void ImplicitConversion(); + void MinMax(); DECLARE_NO_COPY_CLASS(MetaProgrammingTestCase) }; @@ -77,13 +79,6 @@ void MetaProgrammingTestCase::IsMovable() void MetaProgrammingTestCase::ImplicitConversion() { - // wxImplicitConversionType<> is used to implement wxMax(). We test it - // indirectly through that here. - - // test that wxMax(1.1,1) returns float, not long int - float f = wxMax(1.1f, 1l); - CPPUNIT_ASSERT_EQUAL( 1.1f, f); - #ifndef wxNO_RTTI CPPUNIT_ASSERT(typeid(wxImplicitConversionType::value) == typeid(int)); CPPUNIT_ASSERT(typeid(wxImplicitConversionType::value) == typeid(unsigned)); @@ -92,3 +87,19 @@ void MetaProgrammingTestCase::ImplicitConversion() #endif #endif // !wxNO_RTTI } + +void MetaProgrammingTestCase::MinMax() +{ + // test that wxMax(1.1,1) returns float, not long int + float f = wxMax(1.1f, 1l); + CPPUNIT_ASSERT_EQUAL( 1.1f, f); + + // test that comparing signed and unsigned correctly returns unsigned: this + // may seem counterintuitive in this case but this is consistent with the + // standard C conversions + CPPUNIT_ASSERT_EQUAL( 1, wxMin(-1, 1u) ); + + CPPUNIT_ASSERT_EQUAL( -1., wxClip(-1.5, -1, 1) ); + CPPUNIT_ASSERT_EQUAL( 0, wxClip(0, -1, 1) ); + CPPUNIT_ASSERT_EQUAL( 1, wxClip(2l, -1, 1) ); +}