Casting a postdecrement operand

kenny at uiucdcsb.CS.UIUC.EDU kenny at uiucdcsb.CS.UIUC.EDU
Wed Jun 18 02:43:00 AEST 1986


/* Written 11:52 am  Jun 12, 1986 by davidsen at steinmetz.UUCP in uiucdcsb:net.lang.c */
>In article <1273 at ulysses.UUCP> jss at ulysses.UUCP writes:
>>In article <114 at romp.UUCP> lwh at romp.UUCP (lwh) writes:
>>>My version of pcc on the IBM RT PC allows the following expression:
>>>
>>>		((struct abc *)cbap)++;
>>>
>>>
>>>to increment cbap by 500. It appears that the ANSI standard doesn't say
>>>anything about the legality of this syntax.  
>>
>>"++" requires an lvalue. A cast produces a value but not an lvalue,
>>so this is not legal in ANSI (or in K&R ) C. 
>>
>>Jerry Schwarz
>>Bell Labs, MH
>
>The variable 'cbap' is a pointer. The cast '(struct abc *)' is a
>pointer cast. I can use '((struct abc *)cbap)' with indirects and
>subscripts and anywhere that I can use an Lvalue, so I really believe
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- NO!
>that the expression is legal.
>
>Now, as to being *portable*. There is some language in the X3J11
>proposed standard about possible loss of information and
>non-portability when pointers are cast. This is why the 'void *' type
>was introduced (in part) to have a pointer which could hold any valid
>data address. However, there is no guarantee that when the address of
>one data type, however obtaining, is cast to a pointer to another data
>type that the result will be valid.
>
>If I recall correctly the term in use in X3J11 for stuff was "valid but
>non-portable". Sorry I can't remember for sure who said it. I hope this
>clarifies the question somewhat (it does in my mind, anyway).
[ ... ]

/* End of text from uiucdcsb:net.lang.c */

No, no, no!  You can *dereference* ((struct abc *) cbap).  You can subscript
it, you can put a * in front of it, you can use it anywhere you can use a
pointer *rvalue*.  What you can't do is use it in any context requiring an
*lvalue*.  You can't ++ it, you can't -- it, you can't = (+=, -=, ...) into
it, and you can't put an & in front of it.  If you wanted to force
incrementation of cbap as a (struct abc *) and throw portability to the
winds, and you know that different types of pointer share the same
representation on your machine, you might try ++*((struct abc **) &cbap).
I wouldn't.

Now, class, three times slowly:  Casts are rvalues.  Casts are rvalues.
Casts are rvalues.

Kevin Kenny
University of Illinois at Urbana-Champaign
UUCP: {ihnp4,pur-ee,convex}!uiucdcs!kenny 
CSNET:	kenny at UIUC.CSNET
ARPA:	kenny at B.CS.UIUC.EDU	(kenny at UIUC.ARPA)

"Yes, understanding today's complex world is a bit like having bees live in
your head, but there they are."



More information about the Comp.lang.c mailing list