Subject: Re: gcc optimizer bug in netbsd-1-6 on alpha (gcc 2.95.3 20010315 (release) (NetBSD nb3))
To: NetBSD/alpha Discussion List <port-alpha@NetBSD.ORG>
From: Martin Husemann <martin@duskware.de>
List: tech-toolchain
Date: 08/15/2003 08:27:56
On Thu, Aug 14, 2003 at 02:40:22PM -0400, Greg A. Woods wrote:

> 		unsigned long inet = 0;		/* an IPv4 address */
> 	
> 		printf("parse_address(): inet addr given: [%s]\n",
> 		       inet_ntoa(*((struct in_addr *) &inet)));

This code is completely bogus and will not work on any 64 bit platform,
besides maybe by a lot of luck and/or a buggy compiler.

On my alpha:

sizeof(unsigned long) = 8, sizeof(struct in_addr) = 4

So what do you expact the dereference of the casted pointer to mean? Should
it pass a 4 byte object to inet_ntoa (and which half of the 8 byte object
you started from)?

Anyway, C99 does not allow such casts, and accordingly gcc 3.3.1 warns about
it, with the now already famous:

test.c:14: warning: dereferencing type-punned pointer will break strict-aliasing rules

While this is only a warning, the generated code does not do what you expect
it to do. Example (on sparc64, gcc 3.3.1, with inet = 0 replaced by 
inet = 0x0102030405060708):

Compiled with -O (does not include -fstrict-alias):
parse_address(): inet addr given: [1.2.3.4]

Compiled with -O2:
parse_address(): inet addr given: [1.0.0.0]

This is *not* a compiler bug. According to the C standard you are invoking
undefined behaviour.

Martin