Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!cmcl2!husc6!panda!genrad!decvax!mcnc!rti-sel!dg_rtp!throopw From: throopw@dg_rtp.UUCP (Wayne Throop) Newsgroups: comp.lang.c Subject: Re: incrementing after a cast Message-ID: <732@dg_rtp.UUCP> Date: Sat, 6-Dec-86 10:11:29 EST Article-I.D.: dg_rtp.732 Posted: Sat Dec 6 10:11:29 1986 Date-Received: Sun, 7-Dec-86 05:26:02 EST References: <349@apple.UUCP> Lines: 60 Summary: I'm sorry, but if you show me this red flag, I feel obliged to charge. > kanner@apple.UUCP (Herbert Kanner) > We would like to solicit some opinions on the legality of [...] > *((sometype *) chp)++; Well, I think it's illegal, Kernighan thinks it's illegal, Ritchie thinks it's illegal, Harbison thinks it's illegal, Steele thinks it's illegal, and (I would venture to guess) all the members of the X3J11 ANSI C group think it is illegal. Is that enough "opinions" for you? Will you now agree that it is Not a Very Good Idea? Go ahead! Argue the point! Make my day! More seriously, the *reason* it is illegal is that casts (at least conceptually, and in many cases actually) *DO* *SOMETHING* to the value they are applied to. Would you expect ((-i)++) to work? Would you expect ((i+j)++) to work? More relevant, would you expect (((float)i)++) to work? I would *NOT* expect them to work, and similarly I do not expect (((some_type *)p)++) to work, either. > Both the portable C compiler and lint happily accept this construct. "This turns out not to be the case." Given this input: 1 char *p; 2 void f(){ 3 ((int *)p)++; 4 } lint on our system says (among other things): (3) illegal lhs of assignment operator If your lint doesn't complain about it, it is buggy. > The idea of the cast is to force chp to be incremented by the size of > sometype. Sure. OK. Fine. But that isn't the way to accomplish this. Try L = *(sometype *)chp; chp = (char *)(((sometype *)chp)+1) It works just as well, and has the advantage of being legal C. Still legal but less portable is to declare chp to be a union of all the relevant pointer types like so: union {sometype *stp; anothertype *atp; someothertype *sotp; } p; and use something like somevalue = *p.stp++; to do the save-value-and-increment-pointer operation. Note that this only works on machines where the various pointer formats are identical, and where the compiler implements unions "the way you expect". -- "Happily, I read English." (Draws sword) "Then read it happily!" --- Exchange in the 1950s production of IVANHOE -- Wayne Throop !mcnc!rti-sel!dg_rtp!throopw