A cast pointer is NOT an lvalue!? (ANSI C)

James Jones jejones at mcrware.UUCP
Mon Oct 10 21:09:29 AEST 1988


In article <479 at midgard.mn.org>, dal at midgard.mn.org (Dale Schumacher) writes:
  [ANSIoid compiler doesn't allow a cast to be used as an lvalue...]
> Since I'm working closely
> with the compiler authors, I was able to talk to them about the compiler
> not handling this construct and was told that the X3J11 proposal states
> clearly (in a footnote) that the result of a pointer cast is NOT an lvalue!
> It appears to late to get this changed in the standard, but I would like
> to know WHY.

This is, in fact, one of the places in which K&R is actually clear.  One can
readily show that a cast cannot be derived from the production for the non-
terminal "lvalue" in the back of the book.  ANSI Draft doesn't have this
production, so I would presume they felt an explicit statement was needed.

I'm not sure, though, that the example you give is really invalid!  A value
with pointer type does not have to be an lvalue to be dereferenced, so that

	*((woof *) p) = woof1;

is OK.  The sorts of constructs forbidden by a cast not being an lvalue are
these:

	{
		register int	i, *ip, *jp;

		((double) i) = 5.0;	/* what on earth is that supposed to do?! */
		((char *) ip) += i; /* someone wants to avoid scaling i, I guess */
		*((char *) ip)++ = *((char *) jp)++;
	}

Now, despite the fact that K&R and ANSI Draft both say or imply that a cast
is not an lvalue, it turns out that some C compilers will let some casts
get by.  (I just tried the second statement in the above block on a Sun 3,
and it compiled without a peep.  In fact, I would tend to wonder whether
most pcc-based compilers have the same, uh, feature, and how much code will
break when moved to an ANSI-conforming compiler.)

		James Jones



More information about the Comp.lang.c mailing list