
On Fri, Apr 18, 2008 at 8:25 AM, Giovanni Piero Deretta <gpderetta@gmail.com> wrote:
On Thu, Apr 17, 2008 at 4:22 AM, Mat Marcus <mat-lists@emarcus.org> wrote:
Hi,
In boost 1.35.0 I'm getting many of the following warnings from gcc-4.2.0 under cygwin when using boost/functional/hash:
../boost_libraries/boost/functional/detail/hash_float.hpp: In function 'size_t boost::hash_detail::float_hash_impl(float)': ../boost_libraries/boost/functional/detail/hash_float.hpp:75: warning: dereferencing type-punned pointer will break strict-aliasing rules ../boost_libraries/boost/functional/detail/hash_float.hpp: In function 'size_t boost::hash_detail::float_hash_impl(double)': ../boost_libraries/boost/functional/detail/hash_float.hpp:82: warning: dereferencing type-punned pointer will break strict-aliasing rules ../boost_libraries/boost/functional/detail/hash_float.hpp: In function 'size_t boost::hash_detail::float_hash_impl(long double)': ../boost_libraries/boost/functional/detail/hash_float.hpp:90: warning: dereferencing type-punned pointer will break strict-aliasing rules
Is this a boost bug, or a spurious warning? Is there a fix or a sound workaround?
The warning is correct. GCC can produce wrong code with -fstrict-aliasing (the default). Casting a float* to to uint32_t* and dereferencing the result is UB (if the pointer didn't point to an integer in the first place of course).
Changing:
inline std::size_t float_hash_impl(float v) { boost::uint32_t* ptr = (boost::uint32_t*)&v; std::size_t seed = *ptr; return seed; }
to
inline std::size_t float_hash_impl(float v) { std::size_t seed; std::memcpy(&x, &v, sizeof(x)); return seed; }
should work and should produce optimal code, at least with a recent gcc. Similar transforms could be applied to float_has_impl([long] double). BTW, is BOOST_HASH_USE_x86_BINARY_HASH only defined for __CYGWIN__ or I'm reading the #ifdefs incorrectly?
-- gpd
Thanks for the explanation and the patch. - Mat