Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxn!ihnp4!inuxc!pur-ee!uiucdcs!uiucdcsb!kenny From: kenny@uiucdcsb.CS.UIUC.EDU Newsgroups: net.lang.c Subject: Re: Casting a postdecrement operand Message-ID: <139200031@uiucdcsb> Date: Tue, 17-Jun-86 12:43:00 EDT Article-I.D.: uiucdcsb.139200031 Posted: Tue Jun 17 12:43:00 1986 Date-Received: Thu, 19-Jun-86 08:58:00 EDT References: <114@romp.UUCP> Lines: 60 Nf-ID: #R:romp.UUCP:114:uiucdcsb:139200031:000:2561 Nf-From: uiucdcsb.CS.UIUC.EDU!kenny Jun 17 11:43:00 1986 /* Written 11:52 am Jun 12, 1986 by davidsen@steinmetz.UUCP in uiucdcsb:net.lang.c */ >In article <1273@ulysses.UUCP> jss@ulysses.UUCP writes: >>In article <114@romp.UUCP> lwh@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@UIUC.CSNET ARPA: kenny@B.CS.UIUC.EDU (kenny@UIUC.ARPA) "Yes, understanding today's complex world is a bit like having bees live in your head, but there they are."