Article View: comp.std.c
Article #3453Re: (no subject) [cast expression as an lva
From: Chris Torek
Date: Wed, 11 Oct 1995 04:40
Date: Wed, 11 Oct 1995 04:40
66 lines
3462 bytes
3462 bytes
>>> ((char *)src)++; /* src is an (int *) */ In article t78@inferno.mpx.com.au, msmith@jolt.mpx.com.au (Michael Smith) writes: >>I **THINK** that this was considered legal using K&R1 style C. No, this was never legal. In article <45ef3f$n8u@engnews2.eng.sun.com> Steve Clamage <clamage@Eng.Sun.COM> answers: >K&R1 said that a cast yielded a value, not an lvalue. [Stephen >Johnson's] PCC compiler did not check for this violation, and the >code it generated happened to do what the programmer intended. ... >I don't know what would have happened if the programmer wrote > float f; > (double)f = 10.0; /* will the compiler complain? */ > long l; > (short)l = 5; /* how about this? */ PCC stored information about expressions in `trees'. Each tree node represented something in the source, such as a constant, a variable, an assignment operator, or a conversion. There were in fact two kinds of conversion nodes, SCONV (a `scalar conversion') and PCONV (a `pointer conversion'). A number of the optimization passes removed unnecessary conversions, so that the code generator did not have to have templates such as `to convert from int to int, emit no code'. On most machines, many (or even all) PCONV conversions could be removed by rewriting the pointer type. Unfortunately, one such conversion remover ran *before* semantics checking (directly from buildtree(), I believe). This saved runtime space and time at the expense of error checking. By the time the increment operator handler looked at the `((char *)src)++' tree, the cast was gone and the tree simply claimed that the goal was to increment the variable `src' with the type `char *'. Thus, the answer is that the above two casts (which use SCONV nodes and change the size and representation as well as the type) were not removed, and the compiler would complain. >... instead of > ((char*)src)++; >you can write > (*(char**)(&src))++; If `src' has type `int *' and this is a Data General Eclipse, `(*(char **)&src)++;' adds 2 bytes to `src'. On such a machine, PCC would retain the PCONV node would therefore have complained. Thus, in effect, PCC defined an lvalue cast as: `Do the cast if and only if the cast generates no code.' There is no such construct in portable C. On the other hand, no one really *wants* such an operation. What they usually *want* is the equivalent of: src = (int *)((char *)src + 1); (still assuming `src' has type `int *'). Of course, on the DG, this leaves `src' unchanged, because adding one byte to a word still leaves you pointing to the same word. In other words, this code is hopelessly broken; the only thing that can be done with it is to throw it away. -- In-Real-Life: Chris Torek, Berkeley Software Design Inc Berkeley, CA Domain: torek@bsdi.com +1 510 549 1145 `... if we wish to count lines of code, we should not regard them as ``lines produced'' but as ``lines spent.'' ' --Edsger Dijkstra
Technical Details
Message-ID:
<45fhs8$2ra@elf.bsdi.com>Path:
arc1-ca.pugleaf.net!cs.umd.edu!not-for-mailReferences:
<45e68p$t78@inferno.mpx.com.au> <45ef3f$n8u@engnews2.eng.sun.com>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!cs.umd.edu!not-for-mail From: torek@elf.bsdi.com (Chris Torek) Newsgroups: comp.std.c,comp.lang.c,comp.unix.solaris Subject: Re: (no subject) [cast expression as an lva Date: 10 Oct 1995 21:40:40 -0700 Organization: Berkeley Software Design, Inc. Distribution: inet Message-ID: <45fhs8$2ra@elf.bsdi.com> References: <45e68p$t78@inferno.mpx.com.au> <45ef3f$n8u@engnews2.eng.sun.com> Reply-To: torek@bsdi.com NNTP-Posting-Host: elf.bsdi.com