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