Re: strict aliasing violation
Piotr Wyderski piotr.wyder...@gmail.com writes: 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_castconst std::uint32_t*(reinterpret_castconst char*(v))); } but I expected char* to be allowed to alias anything. Only when used as the type to access the object, but you access it as uint32_t. The intermediate cast is irrelevant for aliasing consideration. Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different.
Re: strict aliasing violation
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_castconst std::uint32_t*(reinterpret_castconst 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; Richard. Best regards Piotr Wyderski
Re: strict aliasing violation
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_castconst std::uint32_t*(reinterpret_castconst 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. 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. -- Insert your favourite quote here. Erik Trulsson ertr1...@student.uu.se
Re: strict aliasing violation
On 01/25/2010 02:42 PM, Erik Trulsson 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_castconst std::uint32_t*(reinterpret_castconst 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. Of course it is allowed. It's a legitimate gcc extension, and it's supported by many other compilers too. Andrew.
Re: strict aliasing violation
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_castconst std::uint32_t*(reinterpret_castconst 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.
Re: strict aliasing violation
Andrew Haley wrote: union { float f; uint32 i; } u = {.f = v}; return u.i; Nope, that is not allowed either. Of course it is allowed. It's a legitimate gcc extension, and it's supported by many other compilers too. It's a C extension, according to the documentation. In C++ mode (-std=gnu++0x) the compiler does not understand the u = {.f = v} statement. Is it a feature or a bug? ;-) Best regards Piotr Wyderski
Re: strict aliasing violation
On 25 January 2010 15:51, Piotr Wyderski: Andrew Haley wrote: union { float f; uint32 i; } u = {.f = v}; return u.i; Nope, that is not allowed either. Of course it is allowed. It's a legitimate gcc extension, and it's supported by many other compilers too. It's a C extension, according to the documentation. In C++ mode (-std=gnu++0x) the compiler does not understand the u = {.f = v} statement. Is it a feature or a bug? ;-) A feature; the C++ committee decided not to support designated initializers.