
[mailto:boost-bounces@lists.boost.org] On Behalf Of Giovanni Piero Deretta Sent: Friday, April 18, 2008 8:26 AM To: boost@lists.boost.org Subject: Re: [boost] [1.35][functional] gcc-4.2:dereferencing type-punnedpointer will break strict-aliasing rules
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; }
/x/seed/ ??