On Mon, Jan 25, 2010 at 3:42 PM, Erik Trulsson <ertr1...@student.uu.se> wrote:
> On Mon, Jan 25, 2010 at 02:19:04PM +0100, Richard Guenther wrote:
>> On Mon, Jan 25, 2010 at 1:24 PM, Piotr Wyderski
>> <piotr.wyder...@gmail.com> wrote:
>> > I have a hash function hash(T v) overloaded for
>> > all integral types. I want to provide a variant for
>> > float and double, which should work as follows:
>> > take the floating-point value, treat its binary
>> > representation as uint32_t/uint64_t and use
>> > the result as a parameter for an integral hash().
>> >
>> > However, GCC warns me about strict aliasing
>> > rules violation, which is technically correct, but
>> > in this case is intended. How do I perform this
>> > conversion ina GCC-friendly way? Even that
>> > produces a warning:
>> >
>> >    inline hash_type hash(float v) {
>> >
>> >        return hash(*reinterpret_cast<const
>> > std::uint32_t*>(reinterpret_cast<const char*>(&v)));
>> >    }
>> >
>> > but I expected char* to be allowed to alias anything.
>>
>> But your access is via std::uint32_t *, not char.  Use a
>> union like
>>
>>   union { float f; uint32 i; } u = {.f = v};
>>   return u.i;
>
> Nope, that is not allowed either.

It's a GCC extension sanctioned by the latest revision of the C99
standard.

> What probably would work is to use memcpy() to copy the contents
> of an object of type float into another object of type uint32_t and
> then use the value of that object.  As long as uint32_t does not have
> any trap representations that should be safe.

At least 6.5/6 does not explicitly suggest this.  But it happens
to work with GCC as well.

Richard.

Reply via email to