Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site l5.uucp Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!seismo!lll-crg!well!l5!gnu From: gnu@l5.uucp (John Gilmore) Newsgroups: net.bugs.4bsd,net.lang.c Subject: Re: C compiler *correctly* handles casts on lhs Message-ID: <130@l5.uucp> Date: Fri, 20-Sep-85 18:33:28 EDT Article-I.D.: l5.130 Posted: Fri Sep 20 18:33:28 1985 Date-Received: Sun, 22-Sep-85 06:40:38 EDT References: <937@vax2.fluke.UUCP> Organization: Ell-Five [Consultants], San Francisco Lines: 33 Xref: watmath net.bugs.4bsd:1766 net.lang.c:6501 Summary: Casting the left arg of assignment is not valid C. Followups-To: net.lang.c 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.