[net.bugs.4bsd] C compiler *correctly* handles casts on lhs

gnu@l5.uucp (John Gilmore) (09/21/85)

In article <937@vax2.fluke.UUCP>, kurt@fluke.UUCP (Kurt Guntheroth) writes:
> 	The Vax 4.2 C compiler incorrectly generates a fatal error message
> 	when castes to a pointer type appear on the lhs of an assignment.

The left argument of assignment must be an lvalue.  (This is why it's called
an lvalue, for *left*value.)  A cast does not produce an lvalue.

You can almost always get around this depending what you want.  Example:

			struct foo *p;
			((char *)p) = argv[5];	/* Not valid C */

One fix is:		p = (struct foo *) argv[5];
This converts the value of argv[5] to the type of p, and assigns it.
This would be easier if C had a "typeof" operator, since knowledge of
the type of p wouldn't be scattered throughout the program:
			p = (typeof p) argv[5];

Another possibility:	*((char **)&p) = argv[5];
In this case, the left argument is the result of "*", which DOES return
an lvalue.  This says "take the storage location of p, treat it like
a char *, and put argv[5] there".  However, it doesn't work if p is
a register variable.

The two approaches produce different results when the cast involves
a conversion (eg, from int to float).  You can also declare p as a union
to get (even more portably) the effect of the second approach.

> 	The SUN C compiler and other c compilers I have tried correctly
> 	handle this assignment.
Compilers are free to extend the language they will accept.

Any followups to net.lang.c, please.