Is this a bug in some C compilers?

Norman Diamond diamond at csl.sony.JUNET
Thu Jul 20 12:12:44 AEST 1989


In article <800 at sbsvax.UUCP> greim at sbsvax.UUCP (Michael Greim)
asks why the following program compiled and executed:

-> # include <stdio.h>
-> 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 at 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.



More information about the Comp.lang.c mailing list