Must casting destroy lvalueness?

David desJardins desj at brahms
Fri Oct 24 12:11:12 AEST 1986

In article <657 at dg_rtp.UUCP> throopw at dg_rtp.UUCP (Wayne Throop) writes:
>Let's take a similar example.  Would you expect
>        int i;
>        ((short)i)++;
>to do anything sensible?  If so, why?

   In my opinion this should have the result

	* ((short *) &i) = (short) i + 1;

Obviously the result of this operation is machine-dependent (since the effect
of casting int to short is machine-dependent).  But on an appropriate machine
this does indeed have not only a sensible but a *useful* effect -- it will
increment the low bytes of i without carrying into the high bytes.

   At any rate the casting of int to short performs a fundamentally different
operation than does casting of pointers (in Wayne's terminology, the former
"converts" and the latter "takes-as"), and so it is not necessary for one to
make sense in order for the other to be allowed.

   Note also that on most machines the statements

	int *p;
	((int) p)++;

makes sense (it increments the address referenced by p by the addressing unit
of the machine).  In fact this is arguably the correct way to use the value
produced by 'sizeof';

	(int) p += sizeof (foo);

makes sense on any machine where 'sizeof' gives results in multiples of the
addressing unit of the machine, whereas the more common alternative

	p = (int *) ((char *) p + sizeof (foo));

is both clumsier and makes the unnecessary assumption that sizeof (char) == 1.

   Another justification for casting of lvalues is the case of register
variables.  In this case Wayne's alternative syntax doesn't work:

	register int *p;
	(* ((foo **) &p))++;		<== ERROR

But the idea of casting (or "taking-as") the pointer p as a pointer to foo is
still perfectly valid, and the proposed syntax

	((foo *) p)++;

still makes sense, and can be understood and implemented by a compiler.

   -- David desJardins

More information about the Comp.lang.c mailing list