/*

  on x86, sizeof(long long) == 8, sizeof(long) == 4
  
  Ok, I'm back. While fixing my strict aliasing breakerage as Andreas 
  told me to, I found a case where GCC does not warn even with
  -Wstrict-aliasing, but makes incorrect asm code anyway. So I started
  to investigate which optimisation flags in -O2 that causes the
  problem, and have again made a small dummy program demonstrating the
  error:

  gcc -O2 -Wstrict-aliasing -Wall -S test.c

  with all documented optimisation flags included in -O2 enabled
  (including -fstrict-aliasing), the error still does not occur.
  However, with -O2 alone, GCC makes the mistake:
  
  hash:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        movl    -4(%ebp), %eax
        xorl    -8(%ebp), %eax
        leave
        ret
          
  The compiler allocates stack space, and uses it, but without 
  putting anything into it first.

  Debian Linux Pentium 4 system, gcc installed from package system
  from unstable as of 9 Nov 2004.

  gcc -O2 -Wstrict-aliasing -Wall -S test.c

  no messages are generated at compilation. I'm not sure if I have
  understood the strict aliasing rules, but I think the code below
  does violate them (by casting an uint64 array to an uint32 array), 
  although GCC does not think so.

  gcc 2.95 generates correct code.
  gcc 3.2.3 fails
  gcc 3.3.5 fails
  gcc 3.4.2 fails

  /Anders Torger
  
 */

#include <stdio.h>

unsigned long
hash(void *key)
{
    unsigned long long u[1];
    u[0] = *(unsigned long long *)key;
    return ((unsigned long *)u)[0] ^ ((unsigned long *)u)[1];
}

int
main(void)
{
    unsigned long long ull;

    ull = 0xDEADBEAF;
    
    fprintf(stderr, "%08lX\n", hash(&ull));
    return 0;
}

Reply via email to