Re: strict aliasing violation

2010-01-25 Thread Andreas Schwab
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

2010-01-25 Thread Richard Guenther
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

2010-01-25 Thread Erik Trulsson
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

2010-01-25 Thread Andrew Haley
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

2010-01-25 Thread Richard Guenther
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

2010-01-25 Thread 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? ;-)

Best regards
Piotr Wyderski


Re: strict aliasing violation

2010-01-25 Thread Jonathan Wakely
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.