tim@amdcad.UUCP (06/30/87)
OK, now that we have opened up the "style" issue with !p vs p != NULL (sic), how about another: Which operator (pre-increment or post-increment) do you use when the side- effect is the only desired action and the result is discarded, i.e. for (i=0; i<MAX; ++i) vs for (i=0; i<MAX; i++) or ++counter; vs counter++; Personally, the use of post-increment operators here drives me crazy. They have the added meaning of returning the value of the incremented lvalue before the increment. If this is just thrown away, why do it? Also, for some reason (buried deep within my convoluted brain), when quickly scanning code, I tend to recognize ++counter much faster than counter++. -- Tim (now donning asbestos suit) Olson Advanced Micro Devices
markg@amdcad.AMD.COM (Mark Gorlinsky) (06/30/87)
In article <17310@amdcad.AMD.COM> tim@amdcad.AMD.COM (Tim Olson) writes:
.Which operator (pre-increment or post-increment) do you use when the side-
.effect is the only desired action and the result is discarded, i.e.
.
. for (i=0; i<MAX; ++i)
.vs
. for (i=0; i<MAX; i++)
.or
. ++counter; vs counter++;
.
Sorry Tim, I have to disagree with you. I hate to see sloppy 'C' code, when it
can be avoided, but this is perfectly fine. The use of the post-increment or
decrement operator to bump a value up|down, when not being passed as an
argument, doesn't generate any side-effects. Both will produce the same code.
--
Mark Gorlinsky - AMD Processor Products Division/APPS SQA
UUCP: {ucbvax,decwrl,allegra}!amdcad!markg or amdcad!markg@decwrl.dec.com
AT&T: (408) 982-7811
DISCLAIMER: What's mine is mine, not my employers.
beede@hubcap.UUCP (Mike Beede) (07/01/87)
in article <17310@amdcad.AMD.COM>, tim@amdcad.AMD.COM (Tim Olson) says: > > [ question: use ++i or i++ when only side-effect is desired ] > > Personally, the use of post-increment operators here drives me crazy. They > have the added meaning of returning the value of the incremented lvalue > before the increment. If this is just thrown away, why do it? ^-------------------------------------^ Just an observation: all expressions in C return a value. Thus, every ``naked'' expression involves throwing a value away (++i; AND i++;). There is no reason a compiler needs to generate code differently for i++; and ++i; if that is the entire expression (and statement). Maybe some people familiar with the internals of C compilers could comment on this--it may be easier to generate different code for these cases. BTW--I use ``i++''. For me that seems more natural--maybe from using HP calculators for many years (1/2 ;-> ). -- Mike Beede UUCP: . . . !gatech!hubcap!beede Computer Science Dept. ARPA: BEEDE@TECNET-CLEMSON.ARPA Clemson University INET: beede@hubcap.clemson.edu Clemson SC 29631-1906 PH: (803)656-{2845,3444}
platt@emory.uucp (Dan Platt) (07/01/87)
In article <17310@amdcad.AMD.COM> tim@amdcad.AMD.COM (Tim Olson) writes: >OK, now that we have opened up the "style" issue with !p vs p != NULL (sic), >how about another: > >Which operator (pre-increment or post-increment) do you use when the side- >effect is the only desired action and the result is discarded, i.e. > > for (i=0; i<MAX; ++i) >vs > for (i=0; i<MAX; i++) >or > ++counter; vs counter++; > >Personally, the use of post-increment operators here drives me crazy. I prefer post-increment in these cases since i++; reminds me of i += 1; which I find more agreeable. Needless to say, most compilers will handle the above the same way regardless of whether it was pre or post incremented. But then, this is all a matter of taste, and it's a bad idea to call another person's spouse ugly. Otherwise, it's nice having them both around... Dan
bright@dataio.Data-IO.COM (Walter Bright) (07/01/87)
In article <246@hubcap.UUCP< beede@hubcap.UUCP (Mike Beede) writes:
<in article <17310@amdcad.AMD.COM<, tim@amdcad.AMD.COM (Tim Olson) says:
<< [ question: use ++i or i++ when only side-effect is desired ]
<Just an observation: all expressions in C return a value. Thus, every
<``naked'' expression involves throwing a value away (++i; AND i++;). There
<is no reason a compiler needs to generate code differently for i++; and
<++i; if that is the entire expression (and statement).
<
<Maybe some people familiar with the internals of C compilers could comment
<on this--it may be easier to generate different code for these cases.
I speak for Datalight C (I wrote it):
(++i) is always converted to (i += 1) by the parser.
(i++) is converted to (i += 1) if the value of the expression
is not used.
Therefore, the following all produce identical generated code:
++i;
i++;
i += 1;
cg@myrias.UUCP (Chris Gray) (07/02/87)
I'm probably unusual, but I use pre-increment to increment pointer variables
and += to increment numeric variables. I also separate out the increments,
i.e. don't do them inside other expressions. E.g.
char *p;
int i;
...
i = 0;
while (*p != '\0') {
process(*p);
++p;
i += 1;
}
This will look ghastly to many C programmers, but I have my reasons.
I use the two different increment forms because I like the added visual
clues that one is a pointer and one is an integer (incrementing a pointer
does not necessarily add 1, so I prefer not to see a '1'). I use the pre-
increment form since the incrementation is the action being performed by the
"statement" and I want to see the action before its operand.
The biggest reason I have for doing things like this is quite simple - I
program in other languages besides C, and C's idioms don't port to those
languages. My poor brain would just get confused if I forced it to try to
switch idioms on a twice daily basis (the other language changes and editor
changes are bad enough), so I've developed a set of idioms that work in both
of the languages I use a lot. The other language has a proper 'nil' and a
proper 'bool' type, so I use those in C too.
On the subject of 'if's - I would use
if (! isdigit(ch)) ...
and mentally read it as "if not isdigit ch then". I would also use
if (p != NULL) ...
One of the big problems with C's syntax from my point of view is that a lot
of translation is needed to go between the C form and my internal mental form.
--
Chris Gray Myrias Research, Edmonton +1 403 432 1616
{seismo!mnetor,ubc-vision,watmath,vax135}!alberta!myrias!cg
dg@wrs.UUCP (David Goodenough) (07/02/87)
In article <17315@amdcad.AMD.COM> markg@amdcad.UUCP (Mark Gorlinsky) writes: >In article <17310@amdcad.AMD.COM> tim@amdcad.AMD.COM (Tim Olson) writes: >>Which operator (pre-increment or post-increment) do you use when the side- >>effect is the only desired action and the result is discarded, i.e. >> >> for (i=0; i<MAX; ++i) vs for (i=0; i<MAX; i++) > >Sorry Tim, I have to disagree with you. I hate to see sloppy 'C' code, when it >can be avoided, but this is perfectly fine. The use of the post-increment or >decrement operator to bump a value up|down, when not being passed as an >argument, doesn't generate any side-effects. Both will produce the same code. >-- > Mark Gorlinsky - AMD Processor Products Division/APPS SQA I must agree with Mark - I use (and prefer) i++, and EVEN using Lifeboat's BDS C compiler (for the Intel 8080 (Vintage 1979 Micro) :-)) the code for a i++ on its own is: ld hl,(_i) inc hl ld (_i),hl -- dg@wrs.UUCP - David Goodenough +---+ | +-+-+ +-+-+ | +---+
karl@haddock.UUCP (Karl Heuer) (07/02/87)
In article <17310@amdcad.AMD.COM> tim@amdcad.AMD.COM (Tim Olson) writes: >Which operator (pre-increment or post-increment) do you use when the side- >effect is the only desired action and the result is discarded, i.e. >"for (i=0; i<MAX; ++i)" vs "for (i=0; i<MAX; i++)" As we all know, the two forms are identical in this context, and this is purely a question of style. Having said that, I now state that I always use "++i", and justify it as follows: In general, "++i" means (by defn) "i=i+1". "i++" means "temp=i, i=i+1, temp". The first form is simpler; I don't need the extra "power" of the postfix operator, so I don't use it. (I think this is what you were saying, too.) The historical reason for my preference: when compiling "(void)++i", the only obvious code to generate is "i=i+1", but a sufficiently stupid compiler might translate "(void)i++" into "temp=i; i=i+1" and not notice that the temp remains unused. This turns out not to be the case for any compiler I know of, but you never know. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint (Please, no quibbles like "what if `i' is an expression with side effects".)
billj@zaphod.UUCP (07/04/87)
In article <246@hubcap.UUCP> beede@hubcap.UUCP (Mike Beede) writes: >There >is no reason a compiler needs to generate code differently for i++; and >++i; if that is the entire expression (and statement). Yet in the opening section of the C++ Book, we find "The name C++ was coined by Rick Mascitti. The name signifies the evolutionary nature of the changes from C. '++' is the C increment operator. The slightly shorter name C+ is a syntax error; it has also been used as the name of an unrelated language. Connoisseurs of C semantics find C++ inferior to ++C." I suspect the reason is that, as others have mentioned, C++ implies that the value of the expression is determined before the increment. Are Bjarne or the other abovementioned connoisseurs listening, and willing to reveal the answer? -- Bill Jones, Develcon Electronics, 856 51 St E, Saskatoon S7K 5C7 Canada uucp: ...ihnp4!sask!zaphod!billj phone: +1 306 931 1504
edk@ghsvax.UUCP (Ed Kaulakis) (07/05/87)
Many compilers will materialize the (returned old value) of i++ even when nobody wants it, but will do better with ++i.
jss@hector..UUCP (Jerry Schwarz) (07/06/87)
In article <1748@zaphod.UUCP> billj@zaphod.UUCP (Bill Jones) writes: >... in the opening section of the C++ Book, we find > > "The name C++ was coined by Rick Mascitti. ... > Connoisseurs of C semantics find C++ inferior to ++C." > >I suspect the reason is that, as others have mentioned, C++ implies >that the value of the expression is determined before the increment. >Are Bjarne or the other abovementioned connoisseurs listening, and >willing to reveal the answer? I was around when the name was coined by Rick. The reason C++ was chosen rather than ++C was the "obvious" lexical one. A name containing a "+" is pretty radical, a name beginning with it would have potentially created a real headache. Jerry Schwarz Bell Labs, Murray Hill
escott@BONNIE.UCI.EDU (Scott Menter) (07/07/87)
Actually, I seem to remember that on at least one compiler I was using, it was better to use pre-auto-decrement and post-auto-increment, when possible. The reason was that the machine had a pre-decrement and a post-increment addressing mode (for stack manipulation, presumably) which were a win compared to ADD #1,MEMLOC. Er, maybe it was the OS9 Level II compiler for the 6809... I'm not sure. Anybody else have an example of this? +-------------------------------------------------------------------------+ Scott Menter UCI ICS Computing Support Group Univ. of Calif. at Irvine (714) 856 7552 Irvine, California 92717 Internet: escott@ics.uci.edu UUCP: ...!ucbvax!ucivax!escott Bitnet: escott@uci CSNet: escott%ics.uci.edu@csnet-relay Internet (with Name Server): escott@deis.uci.edu +-------------------------------------------------------------------------+
ark@alice.UUCP (07/07/87)
In article <2710@ulysses.homer.nj.att.com>, jss@hector.UUCP writes: > >I suspect the reason is that, as others have mentioned, C++ implies > >that the value of the expression is determined before the increment. > >Are Bjarne or the other abovementioned connoisseurs listening, and > >willing to reveal the answer? > > I was around when the name was coined by Rick. The reason C++ was > chosen rather than ++C was the "obvious" lexical one. A name > containing a "+" is pretty radical, a name beginning with it > would have potentially created a real headache. Although Jerry's comment is correct as far as history goes, C++ is really a better name than ++C. The reason is that C++ means "increment C, return its old value" which is exactly what the C++ translator does.
ado@elsie.UUCP (07/07/87)
> Which operator (pre-increment or post-increment) do you use when the side- > effect is the only desired action and the result is discarded, i.e. > "for (i=0; i<MAX; ++i)" vs "for (i=0; i<MAX; i++)" I use "++i", only because the symbols appear in the same order as that of the English language description I prefer for the construct ("increment i"). -- "The Moon must wait--we have unfinished business here on Earth." UUCP: ..seismo!elsie!ado ARPA: elsie!ado@seismo.CSS.GOV Elsie and Ado are trademarks of Borden, Inc. and Ampex.
dg@wrs.UUCP (07/07/87)
In article <43@ghsvax.UUCP> edk@ghsvax.UUCP (Ed Kaulakis) writes: > > Many compilers will materialize the (returned old value) of i++ even >when nobody wants it, but will do better with ++i. Ye gads! what braindamaged piece of software are you using?? - I've worked with more compilers than I can name, and even my old faithful vintage 1979 copy of BDS C for the good old Intel 8080 doesn't F*** up when doing a i++ as opposed to a ++i. (I don't know about 8086 compilers, I haven't had the misfortune to have been forced to work on a mess dos machine :-}). P.S. These flames are _NOT_ aimed at Ed Kaulakis - he gets my deepest condolences for haveing to use poorly written software, - my blowtorch is pointed at whoever wrote the compiler(s) in question. -- dg@wrs.UUCP - David Goodenough +---+ | +-+-+ +-+-+ | +---+
escott@BONNIE.UCI.EDU (07/08/87)
(My previous message seems to have not gotten through; sorry if you get two notes just like this one). Actually, I once used a compiler (I don't remember which; maybe it was the os9 level II 6809 compiler) where "i++" and "++i" compiled into slightly different code. Apparently the instruction set had a "post-increment" and "pre-decrement" addressing mode (macro-11 has this too, unless I'm mistaken). So, if you used pre-auto-decrement ("--i"), or post-auto-increment ("i++"), you had the advantage of this addressing mode. Ever since, my habit has been to use increment and decrement in those forms, but I (am somewhat embarrassed to) admit that my memory of the details is dim. +-------------------------------------------------------------------------+ Scott Menter UCI ICS Computing Support Group Univ. of Calif. at Irvine (714) 856 7552 Irvine, California 92717 Internet: escott@ics.uci.edu UUCP: ...!ucbvax!ucivax!escott Bitnet: escott@uci CSNet: escott%ics.uci.edu@csnet-relay Internet (with Name Server): escott@deis.uci.edu +-------------------------------------------------------------------------+
guy@gorodish.UUCP (07/09/87)
> Actually, I once used a compiler (I don't remember which; maybe it was the > os9 level II 6809 compiler) where "i++" and "++i" compiled into slightly > different code. Apparently the instruction set had a "post-increment" and > "pre-decrement" addressing mode (macro-11 has this too, unless I'm mistaken). > So, if you used pre-auto-decrement ("--i"), or post-auto-increment ("i++"), > you had the advantage of this addressing mode. If "i" is of an *integral* type, and its value isn't being used (i.e., it's being used in a statement like i++; /* just increment "i", don't use the old or new value */ ) the compiler isn't very likely to use the addressing mode, since most instructions using addressing modes tend to reference what the register in question points to, and "i" isn't likely to point to something interesting (no, you probably don't want to try an instruction like "tst", either, since "i" may be "pointing" to a location that causes a fault when referenced - or worse). As such, in most if not all cases, if "i" is of an integral type, the compiled code for i++; and ++i; should be equally good (it certainly is in our compiler). The same might arguably be true even if "i" is of a pointer type, since neither of those statements refer to what "i" points to, and as such shouldn't be compiled into code that uses those addressing modes. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
arnold@apollo.UUCP (07/09/87)
In article <1748@zaphod.UUCP> billj@zaphod.UUCP (Bill Jones) writes: >Yet in the opening section of the C++ Book, we find > > "The name C++ was coined by Rick Mascitti. The name signifies > the evolutionary nature of the changes from C. '++' is the C > increment operator. The slightly shorter name C+ is a syntax > error; it has also been used as the name of an unrelated > language. Connoisseurs of C semantics find C++ inferior to > ++C." This is brought to you courtesy of the people who consider char* ptr; to be good style. I wouldn't put too much faith in their assertions of their own connoisseur-ship. Their code is probably the ugliest *published* C code (from a stylistic viewpoint) that I have seen. "i++" is what I learned, and although I can hardly claim to be one of the original C programmers, I do go back some ways, and picked up most of my style from the kernal (which wasn't perfect, but was the largest block of extant C code available). Not that it makes any difference on any compiler worth a bucket of warm cow spit... Ken Arnold P.S. Just to avoid someone asking, the reason I consider the above variable declaration to be ugly style is that char* p1, p2; doesn't do what it implies it ought to do. The '*' still is a modifier of p1, even though it is *strongly* attached visually to the type, which it is not a part of at all. In other words, the visual binding of the '*' to "char" is exactly opposity the syntactic binding of '*' to p1; or, more succintly, the layout lies about the meaning. If you want to discuss *this* style point, please change the subject line. I'm just using it as an example of why *not* to trust the C++ people on style.
bobmon@iucs.UUCP (07/09/87)
escott@BONNIE.UCI.EDU (Scott Menter) writes: > >Actually, I once used a compiler (I don't remember which; maybe it was the >os9 level II 6809 compiler) where "i++" and "++i" compiled into slightly >different code. Apparently the instruction set had a "post-increment" and >"pre-decrement" addressing mode (macro-11 has this too, unless I'm mistaken). >So, if you used pre-auto-decrement ("--i"), or post-auto-increment ("i++"), >you had the advantage of this addressing mode. [...] PDP-11's (Macro-11), 6809's, 6502's and 680x0's all feature post-increment and pre-decrement addressing modes. However, since the inc/decrement of the relevant index register is a side effect of some instruction that's USING that addressing mode, it isn't obvious to me that the use of that mode is exceptionally efficient when the side effect is all you want. Nor is it obvious to me that all compilers would pick up on this "optimization" (although I'm sure that some do).
rwhite@nu3b2.UUCP (Robert C. White Jr.) (07/11/87)
In article <223@wrs.UUCP>, dg@wrs.UUCP (David Goodenough) writes: > In article <43@ghsvax.UUCP> edk@ghsvax.UUCP (Ed Kaulakis) writes: > > > > Many compilers will materialize the (returned old value) of i++ even > >when nobody wants it, but will do better with ++i. > > Ye gads! what braindamaged piece of software are you using?? - I've worked > +---+ Pardon my foolish inquiry... isnt i++ SUPPOSED to return the old value of i AND THEN increment it's stored value. Ed, if this isnt what you mean ignore this and then post an example of the misfunctioning code, I for one would love to see a murdered code fragment and credits for the complier. [as a warning against purchase] If this is what you mean.... well, I don't know what to say :-) Robert. Disclaimer: My mind is so fragmented by random excursions into a wilderness of abstractions and incipient ideas that the practical purposes of the moment are often submerged in my consciousness and I don't know what I'm doing. [my employers certainly have no idea]
guy%gorodish@Sun.COM (Guy Harris) (07/12/87)
> > > Many compilers will materialize the (returned old value) of i++ even > > >when nobody wants it, but will do better with ++i. > > > > Ye gads! what braindamaged piece of software are you using?? - I've worked > > Pardon my foolish inquiry... isnt i++ SUPPOSED to return the old > value of i AND THEN increment it's stored value. No, it's supposed to evaluate to the old value of "i", but not necessarily "return" it. If that value is merely going to be thrown away - remember, lots of times you just want to increment "i", without using its value, so you write i++; or ++i; as statements by themselves - a compiler shouldn't produce code that wastes resources by materializing that value anywhere. I.e., if i++; as a statement by itself generates something like: move i,r0 add #1,i then the compiler that generated that is stupid. That statement should compile to add #1,i just as ++i; should. ("Compiler" here includes all passes; for instance, PCC tends to produce sloppy code in some cases because 1) it's a lot more work for it to do it right and 2) it knows that the peephole optimizer can clean up after it more easily than it can generate the proper code.) Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
exodus@uop.UUCP (Freddy Kreuger) (07/12/87)
> In article <43@ghsvax.UUCP> edk@ghsvax.UUCP (Ed Kaulakis) writes: > >Many compilers will materialize the (returned old value) of i++ even >when nobody wants it, but will do better with ++i. Who's C compiler are you using? Tiny-C? Well, this is sort-of machine specific (although there are a lot of 680xx boxes out there) but here goes: The following C code: main() { int i,j; i=0; i++; ++i; j=i++; j=++i; } Produces: (Only the '<='s were added by me...) / module name inc_test .shri .globl main_ main_: link a6, $-4 <= int i,j; clr -2(a6) <= i=0 addq $1, -2(a6) <= i++ addq $1, -2(a6) <= ++i move -2(a6), d0 <= j=i++ addq $1, -2(a6) <= "" move d0, -4(a6) <= "" addq $1, -2(a6) <= j=++i move -2(a6), d0 <= "" move d0, -4(a6) <= "" unlk a6 <= Clean up stack rts <= ...and go home! So my compiler, at least, is semi-intelligent. And I would expect all modern C compilers to be. Or is that too much to ask? Compilers and compiler theory has come a long way since the original C, fortran, cobol, whatever compilers. There are BASIC (forgive me!) compilers out there nowadays that produce code as clean as a few C compilers... No flames please, I'm just going by published benchmarks. So what's all the fuss about, anyways? Are we all fighting over who's C compiler is better? When I buy something that I will depend on to make me money, I want it to work and I want it to work well. As with any tool, it should meet the specifications of the buyer before it should be used. Artists don't do detailed work with axes... Greg Onufer PS. Code above generated with Mark Williams C ver 2.00 on an Atari ST, 1 Meg Ram, 8 Mhz 68000.
greg@utcsri.UUCP (07/13/87)
In article <795@nu3b2.UUCP> rwhite@nu3b2.UUCP (Robert C. White Jr.) writes: >In article <223@wrs.UUCP>, dg@wrs.UUCP (David Goodenough) writes: >> In article <43@ghsvax.UUCP> edk@ghsvax.UUCP (Ed Kaulakis) writes: >> > >> > Many compilers will materialize the (returned old value) of i++ even >> >when nobody wants it, but will do better with ++i. >> >> Ye gads! what braindamaged piece of software are you using?? - I've worked > > Pardon my foolish inquiry... isnt i++ SUPPOSED to return the old >value of i AND THEN increment it's stored value. Ed, if this isnt what >you mean ignore this and then post an example of the misfunctioning code, >I for one would love to see a murdered code fragment and credits for the >complier. [as a warning against purchase] The key is 'when nobody wants it'. And I wouldn't say "Many" compilers unless you use grotty micro compilers on a regular basis. Example: Small-C, for 8080, and its progeny C/80 from Software Toolworks: int i1,i2; /* my examples use externals. You don't want to see how autos are accessed on the 8080 */ func(){ i1= ++i2; LHLD i2 ; get it INX H SHLD i2 ; put it back SHLD i1 ; save result i1= i2++; LHLD i2 INX H SHLD i2 DCX H ; get prev value (i++ treated as (++i)-1 ) SHLD i1 The catch is that the statements "++i2" and "i2++" generate the same code without the SHLD i2. So in the case of "i2++" there is a wasted DCX H, to give the (unused) value of i2++. This is because the code generator uses a 'building block' technique, where each operation produces a canned piece of code, which must leave a value in a register just in case the op is part of a larger expression. For a much more gruesome example of building-block coding, take a look at the code produced for IF(I.LE.J)... in MicrSoft FORTRAN-80 (BTW it includes an incorrect transformation to ((I-J).LE.0) ). Ah, the 8080... and you can reassemble this stuff to run on the 80386!!! -- ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg Have vAX, will hack...
jyegiguere@watmath.UUCP (07/13/87)
In any half-decent compiler the statements ++i; i++; should produce the same code. What we're really discussing here is more of a stylistic thing than anything, and like all stylistic matters this is subject to personal tastes. I prefer the pre-increment form myself, both because it can be easily read as "increment i", but also because it makes the compiler's job easier... it doesn't have to store i in a temp, increment i, then realize that it doesn't need the temp, etc., etc. In other words, it reduces the need for the optimizer. But then again, I don't know if it's worth arguing about. There seem to be other matters that might be more relevant.... like why the ANSI Standard is so wishy-washy (oh, oh, here come the flames.....) --------------------------------------------------------------------- Computer Systems Group CCCCC SSSSS GGGGG Eric Giguere CC SS GG CC SSSSS GG GG jyegiguere@watmath.waterloo.edu CC SS GG GG CCCCC SSSSS GGGGG giguere@watcsg.bitnet University of Wateroo Disclaimer: The opinions expressed above are not intended to represent those of either the Computer Systems Group or the University of Waterloo.
hmc@hwee.UUCP (Hugh Conner) (07/14/87)
In article <246@hubcap.UUCP> beede@hubcap.UUCP (Mike Beede) writes: >in article <17310@amdcad.AMD.COM>, tim@amdcad.AMD.COM (Tim Olson) says: >> >> [ question: use ++i or i++ when only side-effect is desired ] >> >There is no reason a compiler needs to generate code differently for i++; and >++i; if that is the entire expression (and statement). > As I remember the original PDP-11 C compiler did treat the two cases differently. This was because the PDP had an autoincrement addressing mode of the form Op (Rn)+ which meant that register n was used as a pointer to a location and then incremented. This made i++ more efficient that ++i since it could make use of this mode. Similarly the autodecrement mode on the PDP took the form Op -(Rn) thus making --i more efficient than i--. This is probably no longer true of many (or all) systems, but it still affects the way I tend to write programs. -- + "Who are all these people in my office anyway?" + + + + Hugh M. Conner hmc@ee.hw.ac.uk +
m5@bobkat.UUCP (Mike McNally ) (07/15/87)
In article <223@wrs.UUCP>, dg@wrs.UUCP (David Goodenough) writes: > In article <43@ghsvax.UUCP> edk@ghsvax.UUCP (Ed Kaulakis) writes: >> > >> > Many compilers will materialize the (returned old value) of i++ even >> >when nobody wants it, but will do better with ++i. >> >> Ye gads! what braindamaged piece of software are you using?? - I've worked >---------------------------------------------------------------------- >Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg Well, I just tried this on my Integrated Solutions w/ 4.2BSD: main() { int i; i++, 5; } and I got this (useless crud deleted): L15: /*029*/ movl fp@(-4),d0 ;*********** Not necessary /*066*/ addql #1,fp@(-4) /*028*/ moveq #5,d0 I strongly suspect that this machine's compiler is PCC. -- Mike McNally, mercifully employed at Digital Lynx --- Where Plano Road the Mighty Flood of Forest Lane doth meet, And Garland fair, whose perfumed air flows soft about my feet... uucp: {texsun,killer,infotel}!pollux!bobkat!m5 (214) 238-7474
tainter@ihlpg.ATT.COM (Tainter) (07/15/87)
In article <8186@brl-adm.ARPA>, escott@BONNIE.UCI.EDU (Scott Menter) writes: > Actually, I seem to remember that on at least one compiler I was using, > it was better to use pre-auto-decrement and post-auto-increment, when > possible. The reason was that the machine had a pre-decrement and a > post-increment addressing mode (for stack manipulation, presumably) which > were a win compared to ADD #1,MEMLOC. PDP-11 The friendliest family of 16 bit processors around. If the VAX had been a true 32 bit version of this it would be a serious machine. > Scott Menter UCI ICS Computing Support Group Univ. of Calif. at Irvine
bob@Iago.Caltech.EDU (Robert S. Logan) (07/15/87)
I think the difference between ++i; and i++; is mostly a matter of style, with any reasonable compiler. But I prefer i += 1; as a matter of personal taste. I know, I know, three more keystrokes... Even the dullest compiler will probably generate good code when it sees += of a small constant. -- Robert S. Logan Campus Computing Organization, 158-79 Caltech, Pasadena, CA, 91125 818-356-4631 rslogan@caltech.bitnet bob@iago.caltech.edu ...!ucbvax!bob%iago@hamlet.caltech.edu The above opinions are licensed (not sold)...
guy%gorodish@Sun.COM (Guy Harris) (07/16/87)
> >There is no reason a compiler needs to generate code differently for i++; > >and ++i; if that is the entire expression (and statement). > > > > As I remember the original PDP-11 C compiler did treat the two cases > differently. This was because the PDP had an autoincrement addressing > mode... This made i++ more efficient that ++i since it could make use > of this mode. People seem to be missing the point completely. The addressing modes are irrelevant when the value of the expression isn't being used! There is no sequence of code generated for the statement i++; that is not also a valid sequence of code for the statement ++i; Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/16/87)
In article <3453@ihlpg.ATT.COM> tainter@ihlpg.ATT.COM (Tainter) writes: >In article <8186@brl-adm.ARPA>, escott@BONNIE.UCI.EDU (Scott Menter) writes: >>... The reason was that the machine had a pre-decrement and a >> post-increment addressing mode ... >PDP-11 The friendliest family of 16 bit processors around. If the VAX had >been a true 32 bit version of this it would be a serious machine. The VAX has similar addressing modes; even more than the PDP-11 in fact. The VAX was the outcome of an attempt to define an extended PDP-11 architecture. Other than building in support for BCD arithmetic and other "fat", the VAX architecture is not bad and it is certainly a step up from the PDP-11. Any sales problems the VAX might have had were more than likely due to (a) DEC's resistance to UNIX; (b) years during which no cost-effective (by comparison with the competition) models were available. On the other hand, 4BSD ran only on VAXes for several years, and that may have helped VAX sales. In any case I think the VAX has to be classed as a "serious machine"; it's DEC's mainstay and DEC isn't small.
henry@utzoo.UUCP (Henry Spencer) (07/17/87)
> >There is no reason a compiler needs to generate code differently for i++; and > >++i; if that is the entire expression (and statement). > > As I remember the original PDP-11 C compiler did treat the two cases > differently. This was because the PDP had an autoincrement addressing mode > of the form > > Op (Rn)+ > > which meant that register n was used as a pointer to a location and then > incremented. This made i++ more efficient that ++i since it could make use > of this mode.... > This is probably no longer true of many (or all) systems... Actually, it's not true of the 11 either. Sorry, but you have misunderstood. The PDP11 C compiler generates identical code for "i++" and "++i" when they are found in isolation, and it doesn't use autoincrement addressing for either. The autoincrement addressing modes are really useful only in constructs of the form "*i++", because these modes necessarily cause a memory reference to the location pointed at (considering an integer operand as if it were a pointer). Except in the case of "*i++" and suchlike, the compiler has absolutely no guarantee that an integer variable being incremented would be valid as a pointer -- trying to indirect through it could easily cause a trap. So the compiler dares not use autoincrement and autodecrement as increment and decrement primitives except in certain special cases. Incidentally, at least on modern 11s (I can't be bothered digging out all the old timing tables and comparing), autoincrement is slower than an INC instruction if the increment is the sole purpose of the instruction. (Well, true, things are a bit more complex for incrementing pointers, where using autoincrement can be a slight win.) The real win of autoincrement is that IF indirection is already present, autoincrementing costs very little extra. It is indeed true that "*i++" and "*--i" are substantially faster than "*++i" and "*i--" on 11s and many 11-derived architectures (68000, VAX). But removing the "*" makes a big difference. -- Support sustained spaceflight: fight | Henry Spencer @ U of Toronto Zoology the soi-disant "Planetary Society"! | {allegra,ihnp4,decvax,utai}!utzoo!henry
guy%gorodish@Sun.COM (Guy Harris) (07/17/87)
... > i++, 5; > > and I got this (useless crud deleted): > > L15: > /*029*/ > movl fp@(-4),d0 ;*********** Not necessary > /*066*/ > addql #1,fp@(-4) > /*028*/ > moveq #5,d0 > > I strongly suspect that this machine's compiler is PCC. Possibly, although our compiler is also PCC-based and, after deleting the equivalent useless crud, I got addql #0x1,a6@(-0x4) and that *without* the optimizer. In short, any compiler worth its salt can do something reasonable here. I won't contort my coding style to get around compiler inadequacies; I'll complain about the compiler or get a different one (or, perhaps, fix it). Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
edk@ghsvax.UUCP (Ed Kaulakis) (07/22/87)
In article <5068@utcsri.UUCP>, greg@utcsri.UUCP writes: > In article <795@nu3b2.UUCP> rwhite@nu3b2.UUCP (Robert C. White Jr.) writes: > >In article <223@wrs.UUCP>, dg@wrs.UUCP (David Goodenough) writes: > >> In article <43@ghsvax.UUCP> edk@ghsvax.UUCP (Ed Kaulakis) writes: > >> > > >> > Many compilers will materialize the (returned old value) of i++ even > >> >when nobody wants it, but will do better with ++i. > >> > >> Ye gads! what braindamaged piece of software are you using?? - I've worked > > > > Pardon my foolish inquiry... isnt i++ SUPPOSED to return the old > >value of i AND THEN increment it's stored value. Ed, if this isnt what > >you mean ignore this and then post an example of the misfunctioning code, > >I for one would love to see a murdered code fragment and credits for the > >complier. [as a warning against purchase] > > The key is 'when nobody wants it'. And I wouldn't say "Many" compilers unless > you use grotty micro compilers on a regular basis. > > Example: Small-C, for 8080, and its progeny C/80 from Software Toolworks: > [ interesting stuff deleted ] Well, ok, some. I have seen this in a quite modern compiler which doesn't do template matching but relies on register coloring and its associated dataflow analysis, but (currently) has a null peephole optimizer. Now the problem here is that code is generated before any dataflow analysis, and so the register residency of the "returned" value is a fact of life for the register allocator, thus x++ ==> x->tmp; ++x actually touches a tmp register; never mind that this is eliminated by dead code later; it prevents something else living in this register over the x++. One solution of course is to add some template matching to the front end. Another interesting solution is to iterate codegen and allocate for a while... after all, linear programming is formally NP too, and it works this year... This compiler, brain-damaged at this stage of its life, consistently outperforms [pqr]cc derivatives. And now... the envelope please... the compiler in question is Kaulakis Enterprise's retargeting of the Green Hills (VAX base) code generator to Gould. The null peephole and any other brain damage is ours, not Green Hills'.
ka@hropus.UUCP (Kenneth Almquist) (07/24/87)
> I just tried this on my Integrated Solutions w/ 4.2BSD: > > main() > { > int i; > > i++, 5; > } > > and I got this (useless crud deleted): > > movl fp@(-4),d0 ;*********** Not necessary > addql #1,fp@(-4) > moveq #5,d0 > > I strongly suspect that this machine's compiler is PCC. This bug is understandable based upon the way PCC generates code. PCC looks up operators in the code generation table in the file table.c. In generating the code for the statement "i++;", PCC will try to generate code for the "++" operator for side effects only. If Integrated Solutions forgot to provide an entry in the code table to allow PCC to do this, PCC will compute the value of "i++" in a register rather than giving up entirely. I expect that this shouldn't be too hard to fix if you have source. Look in the file table.c. You should find entries for INCR and DECR. If there are no entries for these operators with FOREFF set, add them. I don't know what all the fields in the table mean, but you should be able to guess close enough by looking at the existing entries for INCR and DECR if you have no documentation. The reason Integrated Solutions didn't catch this bug is that the entries in the code table for INCR and DECR are rarely used. PCC has a routine which will go through an expression, replace all occurances of "i++" with "i", and then tack on an "i += n" to the end of the expression, where n is number of occurances of "i++". This is inhibited by operators which place restrictions on the expression evaluation order. In the code quoted above, the routine could not perform its function because the expression contained a comma operator. Kenneth Almquist
apc@cblpe.ATT.COM (Alan Curtis) (08/02/87)
Does this scare anyone (does any else's compiler do the same thing?) main(a) char (*a)[]; { a = 0; printf("a=0x%x\n", a); a++; printf("a=0x%x\n", a); } produces: a=0x0 a=0x0 I realize that is the logical extension of a++ somtimes adding 8,4,23.5, whathavyou, to a, but it still scares me. PS: In my book a++ should add 1 (one, uno, etc). If I wanted to add sizeof(*a) Ida SAID a += sizeof(*a); Oh well, I only work here.... -- This space intentionally left | Alan P. Curtis blank | AT&T,BTL,CB | +1 614 860 4749 -----------------------------------------------| apc@cblpe.ATT.COM Kudos to stargate for redistribution rights | !cbosgd!cblpe!apc
mouse@mcgill-vision.UUCP (der Mouse) (08/07/87)
>> I just tried this on my Integrated Solutions w/ 4.2BSD: >> main() { int i; i++,5; } >> and I got this (useless crud deleted): >> movl fp@(-4),d0 ;*********** Not necessary >> addql #1,fp@(-4) >> moveq #5,d0 I'm surprised nobody has mentioned (I won't say "noticed"!) that not only did the compiler materialize the value of i++ (which is what was under discussion), it also materialized the 5! der Mouse (mouse@mcgill-vision.uucp)
ron@topaz.rutgers.edu (Ron Natalie) (08/09/87)
Doesn't scare me. You do something undefined and you get undefined results. Remember you can assign 0, test for it later, and are guaranteed that no pointer to any object will test to be equal to zero. No one ever said that if you try to use the 0 pointer in expressions that anything determanistic happens when you reference the result. -Ron
throopw@xyzzy.UUCP (Wayne A. Throop) (08/10/87)
> apc@cblpe.ATT.COM (Alan Curtis) > Does this scare anyone (does any else's compiler do the same thing?) > main(a) > char (*a)[]; > { a = 0; printf("a=0x%x\n", a); a++; printf("a=0x%x\n", a); } > produces: > a=0x0 > a=0x0 It doesn't scare me. It perhaps causes me a momentary fright that anybody thought that that should do something sensible, but then I'm used to such things by now. > I realize that is the logical extension of a++ somtimes > adding 8,4,23.5, whathavyou, to a, but it still scares me. > PS: In my book a++ should add 1 (one, uno, etc). > If I wanted to add sizeof(*a) Ida SAID > a += sizeof(*a); What scares me is that a++ *does* always add 1. Never 8, 4, 23.5, or anything else. Always 1. It adds one byte, or one word, or one *whatever* to the address in question. It would be illogical, immoral, byte-chauvanist, and all kinds of perjorative things for it to add one byte to the address of anything but a byte. Granted, most people are under the delusion that all C address types are byte granular offsets into per-process monolithic address segments. But then, C implementors are not bound to abide by the delusions of the masses, thank goodness. But the scariest thing about all this is that *none* *of* *my* *tools* *caught* *this* *bug*!!!! Lint happily passed the program, as did other typecheckers. And the compiler didn't complain (though on our system the output is a=0x0 a=0x1 instead, (but then the behavior is undefined since the program is illegal in the first place, so I can't blame the compiler too harshly... though I *CAN* blame lint and other type-and-usage checkers for falling down on the job). (By the way, for those of you who missed it, the program is illegal for the obvious reason that it increments a pointer to an object of unknown size, but *also* because it performs arithmetic on a null pointer, and of course, this is illegal.) -- At once words appeared on the screen: "Hello. My name is Hank Thoro II. Please type your name." "My whole name?" he typed. "Good. Do you like baseball? Just type Y for Yes or N for No." --- from "Roderick" by John Sladek -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw
dcw@doc.ic.ac.uk (Duncan C White) (08/11/87)
In article <587@cblpe.ATT.COM> apc@cblpe.ATT.COM (Alan Curtis) writes: > Does this scare anyone (does any else's compiler do the same thing?) > main(a) > char (*a)[]; > { a = 0; printf("a=0x%x\n", a); a++; printf("a=0x%x\n", a); } > produces: > a=0x0 > a=0x0 The first thing which really scares me about this program is that the first parameter to main is ARGC - an integer ! Declaring it as 'char (*a)[]' seems highly suspicious.... This program appears to be using a parameter as a yukky way of declaring the variable: the problem can be simplified by declaring 'a' as as a local variable inside main: main() { char (*a)[]; a = 0; printf("a=0x%x\n", a); a++; printf("a=0x%x\n", a); } In article <189@xyzzy.UUCP> throopw@xyzzy.UUCP (Wayne A. Throop) writes: > >....the program is illegal for >the obvious reason that it increments a pointer to an object of unknown >size, but *also* because it performs arithmetic on a null pointer, and >of course, this is illegal. > Yes, Wayne has hit the nail on the head here: a is declared as a pointer to an indefinite sized string. Logically, there's no such thing as an increment operation on it.. However, Wayne also quoted Alan : >> I realize that is the logical extension of a++ somtimes >> adding 8,4,23.5, whathavyou, to a, but it still scares me. >> PS: In my book a++ should add 1 (one, uno, etc). >> If I wanted to add sizeof(*a) Ida SAID >> a += sizeof(*a); and went on to say: > >What scares me is that a++ *does* always add 1. Never 8, 4, 23.5, or >anything else. Always 1. It adds one byte, or one word, or one >*whatever* to the address in question. Agreed, C adds one "unit" according to the type.. But I don't quite see why that scares Wayne : It seems like the most convenient behaviour to me.. one of the commonest cases is where I have an array of elements of a type t, and am sequentially scanning through the array elements using a pointer. The increment operation for such a pointer is surely 'move onto the next element' rather than 'move on one byte' ?? It would be extremely inconvient if I had to always use 'p += sizeof(t)' > ... It would be illogical, immoral, >byte-chauvanist, and all kinds of perjorative things for it to add one >byte to the address of anything but a byte. Agreed... I think Alan is wrong here: if he really wants to add one byte, [well, one char] to something that is a 'pointer to an element of type t' then I guess he should use: p = (int *) ( 1 + (char *) p ); Wayne finishes off: > >But the scariest thing about all this is that *none* *of* *my* *tools* >*caught* *this* *bug*!!!! Lint happily passed the program, as did other >typecheckers.... > Yes - this is very worrying.. any lint gurus out there care to explain why this is not detected ? Duncan. ----------------------------------------------------------------------------- JANET address : dcw@uk.ac.ic.doc| Snail Mail : Duncan White, --------------------------------| Dept of Computing, This space intentionally | Imperial College, left blank...... | 180 Queen's Gate, (paradoxical excerpt from | South Kensington, IBM manuals) | London SW7 ---------------------------------------------------------------------------- Tel: UK 01-589-5111 x 4982/4991 ----------------------------------------------------------------------------
throopw@xyzzy.UUCP (Wayne A. Throop) (08/17/87)
> dcw@doc.ic.ac.uk (Duncan C White) >> throopw@xyzzy.UUCP (Wayne A. Throop) >>What scares me is that a++ *does* always add 1. > Agreed [...] But I don't quite see why that scares Wayne : > It seems like the most convenient behaviour to me.. And to me. I see I misspoke there. I meant to say that I was scared that anybody would think otherwise. Switching to a different article: > strouckn@nvpna1.UUCP (Louis Stroucken 42720) >> msb@sq.UUCP (Mark Brader) >>Actually, *declaring* such a pointer is probably illegal. > I haven't got any ANSI draft here, so I'd better stay out of the > discussion, but: > Please note that "a" is a formal argument of main!! Ok. Noted. The type of "a" is (char (*)[]). That is, "a" is a pointer. > K&R appendix A section 10.4 says on array arguments: > ...formal parameters declared "array of..." are adjusted to read > "pointer to...". Since "a" is a pointer, this passage does not apply. Repeat: THIS PASSAGE DOES NOT APPLY. > The declaration of "a" might as well read "char **a;". "a++;" should > increment "a" with sizeof( char * ) bytes. Wrong. Wrong. Wrong. A formal declared as type (char *[]) "might as well" be declared with type (char **). But that's not what was going on. The formal was of type (char (*)[]), which is not now, never has been, and Bog willing never will be, equivalent to the type (char **). > If I miss something, please let me know. Consider yourself let. I also post, because this is a common and recurring misconception that I'd like to nip in the bud (this instance of it, anyway). -- In analyzing history do not be too profound, for often the causes are quite superficial. --- Emerson
flaps@utcsri.UUCP (08/19/87)
In article <513@ivax.doc.ic.ac.uk> dcw@doc.ic.ac.uk (Duncan C White) writes: >I think Alan is wrong here: if he really wants to add one byte, ^^^^ (not me!) >[well, one char] to something that is a 'pointer to [int]' >then I guess he should use: > > p = (int *) ( 1 + (char *) p ); ...except that when you dereference it you will get an address exception! Come on here, it is MEANINGLESS to do this kind of operation. It's not just that "adding sizeof(int)" is what you probably want, it's that it's the only sensible thing to do. Now, if you keep the result as char *, that's a different story (as in the code for memcpy()). -- // Alan J Rosenthal // \\ // flaps@csri.toronto.edu, {seismo!utai or utzoo}!utcsri!flaps, \// flaps@toronto on csnet, flaps at utorgpu on bitnet. "To be whole is to be part; true voyage is return."
mouse@mcgill-vision.UUCP (der Mouse) (08/30/87)
In article <5272@utcsri.UUCP>, flaps@utcsri.UUCP (Alan J Rosenthal) writes: > In article <513@ivax.doc.ic.ac.uk> dcw@doc.ic.ac.uk (Duncan C White) writes: >> I think [someone - Duncan said "Alan" but Alan said "not me"] is >> wrong here: if he really wants to add one byte, [well, one char] to >> something that is a 'pointer to [int]' then I guess he should use: >> p = (int *) ( 1 + (char *) p ); Yes. But see below for comments on the wisdom of wanting to do such a thing in the first place. > ...except that when you dereference it you will get an address > exception! No, you *may* get an address exception. On a VAX, for instance (and we all know the whole world is a VAX, right? right? :-), this behaves perfectly nicely. Such unaligned pointers will probably be slightly slower, but they work fine. > Come on here, it is MEANINGLESS to do this kind of operation. No, it is machine- and implementation-dependent, which is not the same thing as meaningless. Doing such a thing (moving an int pointer by one char), except in seriously machine-dependent code, is probably indicative of more serious problems. > It's not just that "adding sizeof(int)" is what you probably want, > it's that it's the only sensible thing to do. No, the only sensible *portable* thing to do. der Mouse (mouse@mcgill-vision.uucp)