gjs@k.cs.cmu.edu (Gregory Stein) (06/09/86)
Keywords: I'm working in Megamax C, and I noticed a problem while I was in the debugger. It comes from these statements: for (i = ntables; i--; ) <statement> if (i == -1) <more statements> I would expect this to get the value of i, decrement the stored value, and then exit or execute the statement. Rather, it tests the value before it decrements, and the loop exits with i = 0. Is this a bug in the code generation, or is C supposed to do this? Greg
kim@analog.UUCP (Kim Helliwell ) (06/11/86)
> Keywords: > > > I'm working in Megamax C, and I noticed a problem while I was in the > debugger. It comes from these statements: > > for (i = ntables; i--; ) <statement> > if (i == -1) <more statements> > > I would expect this to get the value of i, decrement the stored value, > and then exit or execute the statement. Rather, it tests the value > before it decrements, and the loop exits with i = 0. Is this a bug > in the code generation, or is C supposed to do this? > > Greg It's not a MegaMax bug, it's a Greg bug (:-). You have the i-- in the slot that is supposed to be the termination condition--so your description sounds like exactly what I would expect to happen. If you want the i-- to decrement i without testing it for equality to 0 first, it has to be after the second semicolon: for (i = ntables; ; i--) <statement> if (i = -1) <more statements> Kim Helliwell
maclab@reed.UUCP (Mac DLab) (06/13/86)
> > Keywords: > > > > > > I'm working in Megamax C, and I noticed a problem while I was in the > > debugger. It comes from these statements: > > > > for (i = ntables; i--; ) <statement> > > if (i == -1) <more statements> > > > > I would expect this to get the value of i, decrement the stored value, > > and then exit or execute the statement. Rather, it tests the value > > before it decrements, and the loop exits with i = 0. Is this a bug > > in the code generation, or is C supposed to do this? > > > > Greg > > It's not a MegaMax bug, it's a Greg bug (:-). Oops! Guess Greg just can't get Rascal out of his head! Scott G.
njt@fisher.UUCP (Nathaniel Thurston) (06/14/86)
In article <219@analog.UUCP> kim@analog.UUCP (Kim Helliwell) writes: >> for (i = ntables; i--; ) <statement> >> if (i == -1) <more statements> >> >> I would expect this to get the value of i, decrement the stored value, >> and then exit or execute the statement. Rather, it tests the value >> before it decrements, and the loop exits with i = 0. Is this a bug >> in the code generation, or is C supposed to do this? >> >> Greg > > for (i = ntables; ; i--) <statement> > if (i = -1) <more statements> > >Kim Helliwell You're both wrong. The first loop should perform the action Greg describes, using the value before decrementing. To have C test the value after decrementing, use --i. In the "fix" that Kim gives, the loop will never exit without a break statement. The correct code is: for (i = ntables; --i; ) <statement> if (i == -1) <more statements> -- Nathaniel Thurston UUCP: {allegra, astrovax, princeton, twg} !fisher!njt BELL: (609) 683-0543 USnail: 106 FitzRandolph Rd., Princeton, NJ 08544
matt@ucla-cs.UUCP (06/16/86)
In article <1436@fisher.UUCP>, njt@fisher.UUCP (Nathaniel Thurston) writes: - In article <219@analog.UUCP> kim@analog.UUCP (Kim Helliwell) writes: - >> for (i = ntables; i--; ) <statement> - >> if (i == -1) <more statements> - >> - >> I would expect this to get the value of i, decrement the stored value, - >> and then exit or execute the statement. Rather, it tests the value - >> before it decrements, and the loop exits with i = 0. Is this a bug - >> in the code generation, or is C supposed to do this? - >> - >> Greg - > - > for (i = ntables; ; i--) <statement> - > if (i = -1) <more statements> - > - >Kim Helliwell - - You're both wrong. The first loop should perform the action Greg describes, - using the value before decrementing. To have C test the value after - decrementing, use --i. In the "fix" that Kim gives, the loop will never - exit without a break statement. - The correct code is: - for (i = ntables; --i; ) <statement> - if (i == -1) <more statements> - -- - I believe Greg is right. When the loop falls through, `i' should end up as -1. If in fact it does not, the C compiler forgot to generate the trailing DEC instruction on that branch of the test. This seems serious, since checking a post-condition like this is fairly common in C; are you sure? Kim's code is wrong, and would never exit (empty condition == true). Also the trailing test has an assignment (i = -1) instead of a conditional (i == -1). Thus, that test would always succeed. Nathaniel's code is wrong, since I presume Greg intended to execute the <more statements> line if the loop fell through (vs. a `break'); these statements would not be executed if the loop fell through at i==0. The correct condition here (if it were the right test, which it ISN'T for traversing arrays) would be `if (i == 0) ...'. Sigh. - Matt ------- UUCP: {ucbvax,ihnp4,randvax,trwrb!trwspp,ism780}!ucla-cs!matt ARPA: matt@LOCUS.UCLA.EDU
baron@runx.OZ (Jason Haines) (06/17/86)
>I'm working in Megamax C, and I noticed a problem while I was in the >debugger. It comes from these statements: > > for (i = ntables; i--; ) <statement> > if (i == -1) <more statements> > >I would expect this to get the value of i, decrement the stored value, >and then exit or execute the statement. Rather, it tests the value >before it decrements, and the loop exits with i = 0. Is this a bug >in the code generation, or is C supposed to do this? > > Greg NEVER confuse the For statement - for(pre-int,test,re-init) <statement block> Try the following: for (i = ntables;;i--) <statement> if (i == -1) < more statements> /* Jason Haines ACSnet: baron@runx * 73 Davidson Avenue CSNET: baron@runx.oz * Concord NSW 2137 ARPA: baron%runx.oz@seismo.css.gov * AUSTRALIA * * UUCP: * {enea,hplabs,mcvax,prlb2,seismo,ubc-vision,ukc}!munnari!runx.oz!baron */
bart@reed.UUCP (Bart Massey) (06/18/86)
In article <219@analog.UUCP> kim@analog.UUCP (Kim Helliwell) writes: >Greg Stein at CMU said... > > I'm working in Megamax C, and I noticed a problem while I was in the > > debugger. It comes from these statements: > > > > for (i = ntables; i--; ) <statement> > > if (i == -1) <more statements> > > > > I would expect this to get the value of i, decrement the stored value, > > and then exit or execute the statement. Rather, it tests the value > > before it decrements, and the loop exits with i = 0. Is this a bug > > in the code generation, or is C supposed to do this? > > It's not a MegaMax bug, it's a Greg bug (:-). You have the i-- in the > slot that is supposed to be the termination condition--so your description > sounds like exactly what I would expect to happen. If you want the i-- > to decrement i without testing it for equality to 0 first, it has to > be after the second semicolon: > > for (i = ntables; ; i--) <statement> > if (i = -1) <more statements> It may be that you have to do this, (BTW, you almost certainly meant "for(i = ntables; i; i--) <statement>") but it's not a "Greg Bug", it's a Megamax bug. Here's a copy of what I wrote Greg, which he probably didn't receive, because of mailer problems... (Sorry, Greg). K&R specify (page 202) that for( i = ntables; i--; ) <statement> should be equivalent to i = ntables; while( i-- ) <statement> They also specify that "When postfix -- is applied to an lvalue the result is the value of the object referred to by the lvalue. After the result is noted, the object is incremented in the same manner as for the prefix -- operator." (page 187) Putting this all together... Imagine that ntables is 37. The while statement will clearly decrement "i" down to one. Then what will happen? Answer: one is boolean true, so "i" will be decremented to zero. The statement will be executed. zero is boolean false. So the statement won't be executed. BUT "I" WILL STILL BE DECREMENTED, as a result of evaluating "i--". Thus, the <statement> will be executed 37 times, (with i = 37 downto 1), and "i" will end up with the value -1. As a cross check, our 4.2BSD C compiler (reasonably close to K&R), when fed the original "for" statement, does indeed set "i" to -1. The Megamax C compiler is probably putting the branch on the wrong side of the decrement. Understandable (perhaps especially so to Greg, who co-authored the original Rascal compiler), but wrong. Sorry for the length of this posting, but it would have been hard for me to say it shorter... Bart Massey ..tektronix!reed!bart
pedz@megamax (06/20/86)
main()
{
int i, j;
for (i = 10; i--;);
j = i;
}
CODE SEG "main"
main:/* global */
LINK A6,L$0
MOVE #10,-2(A6)
L3:
L4:
L2:
MOVE -2(A6),D0 << Get i
SUBQ #1,-2(A6) << do the decrement
TST D0 << do the test
BNE.S L3
L5:
MOVE -2(A6),-4(A6)
L1:
UNLK A6
RTS
L$0: .EQU #-4
_initargcv:/* global */
RTS
Matt gets the cookie this time. The original bug notice was correct
in his statements about how C should behave. The above code segment
shows that in the current release, this is not a bug. I am reasonable
sure that it has never been a bug but perhaps someone has a really old
version. I would suggest that the original poster disassemble his
output and look at the code. I am sure it will be different from
above but the important thing is that the decrement is done before the
test.
Perry Smith
pedz@megamax
kim@analog.UUCP (Kim Helliwell ) (06/24/86)
I submitted the following source to my Megamax compiler: #include <stdio.h> main() { int i; for (i=10;i--;) { printf("%d\n",i); } printf("%d\n",i); } The final value of i was -1, so I don't really think there is a MegaMax bug. Kim Helliwell
tim@ism780c.UUCP (06/25/86)
When are you guys gonna release 3.0? I am using HFS now, and would like to be able to use Megamax C also... -- Tim Smith USENET: sdcrdcf!ism780c!tim || ima!ism780!tim "hey, bay-BEE'...hey, bay-BEE'" Compuserve: 72257,3706 Delphi || GEnie: mnementh
jdb@mordor.ARPA (John Bruner) (06/25/86)
Regarding Megamax bugs, I've discovered that the (2.1b) compiler seems to have trouble with type casts, particularly those in which a value is cast to a narrower type. For instance, one bug which really drove me crazy recently was a piece of code approximately like this: struct win_info *w; typedef unsigned char row_t, col_t; tty_erasep(w, (row_t)0, (col_t)0); The code it generated was (approximately): CLR.W -(SP) CLR.W -(SP) MOVE.L A2,-(SP) JSR tty_erasep ADDQ #4,SP <<- 4, not 8 Another problem I had with casts occurred when I was initializing a data structure. The first element of the structure was an unsigned int. I initialized it to (unsigned)-1 [using a macro]. The compiler generated the correct initialization code but didn't allocate enough space in the data segment; hence, the structure overlapped variables declared later. This also was a real "joy" to find. I don't seem to have as much difficulty with casts to wider types. Since I redefine NULL to be 0 (instead of the incorrect 0L defined in <stdio.h>) I don't run into this problem. Also I discovered that pointers to functions cannot be compared (except to NULL), because two pointers to the same function may not have the same representation. (I understand why this is so, but it is annoying nonetheless.) -- John Bruner (S-1 Project, Lawrence Livermore National Laboratory) MILNET: jdb@mordor [jdb@s1-c.ARPA] (415) 422-0758 UUCP: ...!ucbvax!decwrl!mordor!jdb ...!seismo!mordor!jdb