Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!cs.utexas.edu!uunet!kddlab!titcca!sragwa!wsgw!socslgw!diamond From: diamond@csl.sony.JUNET (Norman Diamond) Newsgroups: comp.lang.c Subject: Re: Is this a bug in some C compilers? Keywords: bug; cc; referencing a pointer as if it were a structure Message-ID: <10583@riks.csl.sony.JUNET> Date: 20 Jul 89 02:12:44 GMT References: <800@sbsvax.UUCP> Reply-To: diamond@riks. (Norman Diamond) Organization: Sony Computer Science Laboratory Inc., Tokyo, Japan Lines: 64 In article <800@sbsvax.UUCP> greim@sbsvax.UUCP (Michael Greim) asks why the following program compiled and executed: -> # include -> struct link { -> struct link * next; -> int count; -> }; -> int fix0; -> struct link * t; -> int fix1; -> main () -> { -> printf ("t lies at %1d, brk is at %1d\n", (int)(&t), (int)sbrk(0)); -> printf ("Addresses of %1d byte objects around t : %1d and %1d\n", -> sizeof(int), (int)(&fix0), (int)(&fix1)); -> t = NULL; -> t.count = 5; -> if (t.count == 5) -> printf ("Assignment worked.\n"); -> else -> printf ("Assignment did not work\n"); -> printf ("Value 5 has been put at address %1d\n", &(t.count)); -> } -> -> Output from VAX running 43bsd: -> % cc test78.c -> "test78.c", line 21: warning: struct/union or struct/union pointer required -> "test78.c", line 22: warning: struct/union or struct/union pointer required -> "test78.c", line 26: warning: struct/union or struct/union pointer required -> % a.out -> t lies at 6008, brk is at 6176 -> Addresses of 4 byte objects around t : 6004 and 6012 -> Assignment worked. -> Value 5 has been put at address 6012 In fact, the answer was discussed very recently, and was described as "weard" [sic]. Your instantiation of this obscure feature is, perhaps, even "wearder." t is a variable, so it may be used as an lvalue. Once upon a time it was legal, almost reasonable and expected (since "union" wasn't invented yet), and only a little bit "weard," to put any lvalue on the left of a dot. The offset on the right of the dot is 4 (the distance from the beginning of a structure containing "count" to the "count" field itself) so t.count refers to an integer 4 bytes after t. Coincidentally a (struct link *) requires 4 bytes so t.count refers to fix1. After the invention of "union," the old practice of arbitrary lvalues on the left of "." was discouraged. The left side now should be a struct or union, should actually contain a field with the name given on the right side, and it might be an rvalue in an expression context. Some compilers still accept the old syntax. Yours did, after giving warnings. -- -- Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.jp@relay.cs.net) The above opinions are inherited by your machine's init process (pid 1), after being disowned and orphaned. However, if you see this at Waterloo or Anterior, then their administrators must have approved of these opinions.