/*
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;
}