[gnu.gcc.bug] constant expression folding problem?

phil@BRL.MIL (Phil Dykstra) (10/06/88)

gcc 1.28  Sun 3/50  SunOS 3.5

The following code:
============================
struct test {
	char	s[32];
	int	i;
};
#define TEST_NULL	((struct test *)0)

char *foo = (char *)(TEST_NULL->s);

main()
{
}
============================
causes:
t.c:7: initializer for static variable is not constant

There is apparently something about that expression that the
constant folder can't reduce.  The Cray C compiler used
to die on this same sort of expression, but they fixed it.
I know of many other C compilers that accept it as well
(Sun, SGI, Alliant, Gould, Convex, Ardent, Pyramid, BSD Vax).
It would be nice if gcc could too.

- Phil

[The code may look terrible, but doing things sort of like this
is important for code that parses and fills in dynamic C data
structures!]

phil@BRL.MIL (Phil Dykstra) (10/08/88)

> The compiler may still barf, since you are trying to dereference a
> NULL pointer (guarnteed to be a problem), ....

A couple of other people fell in a similar pit.  The code (expanded):

	char *foo = (char *)(((struct test *)0)->s);

does *not* dereference any pointers.  `s' is an array so it could
have been written &((struct test *)0)->s[0]), but that is unnecessary,
the (char *) is simply a cast, and perhaps the most subtle:
"((struct test *)0)->" does not dereference through zero, rather
is says that 0 is the *value* (i.e. contents) of the struct pointer.
What the expression really means is "give me the address of the s
array within a structure located at address zero", i.e. what is the
byte offset of s within the structure.  It really is static.

I wasn't kidding what I listed all of the C compilers that can handle
this correctly.

- Phil