karl@haddock (09/01/86)
It's well known that the equivalence between for and while breaks down if there's a "continue" statement. Here's another case I just discovered: main() { char *foo = "outer"; for (;; printf(foo),exit(0)) { char *foo = "inner"; } } This prints "outer" (vax SVR2 compiler), though the for-while equivalence might lead one to expect "inner". Karl W. Z. Heuer (ima!haddock!karl, karl@haddock.isc.com), The Walking Lint
ballou@brahms.BERKELEY.EDU (Kenneth R. Ballou) (09/02/86)
In article <86900030@haddock> karl@haddock writes: > >It's well known that the equivalence between for and while breaks down if >there's a "continue" statement. Here's another case I just discovered: > >main() { > char *foo = "outer"; > for (;; printf(foo),exit(0)) { > char *foo = "inner"; > } >} > >This prints "outer" (vax SVR2 compiler), though the for-while equivalence >might lead one to expect "inner". I don't think the issue here is equivalence of for and while statements. The point is that the scope of the inner 'foo' is the compound statement which is the body of the for statement. So, quite rightly, the 'foo' given as the argument to printf in the third expression of the for statement refers to the most closely nested declaration of 'foo' -- the body of the for statement is one block level higher and is not visible at this point. --------------- Kenneth R. Ballou ...!ucbvax!brahms!ballou Dept. of Mathematics University of California Berkeley, California 94720
mikeb@copper.UUCP (Mike Beckerman) (09/03/86)
In article <15525@ucbvax.BERKELEY.EDU> ballou@brahms.UUCP (Kenneth R. Ballou) writes: >In article <86900030@haddock> karl@haddock writes: >> >>It's well known that the equivalence between for and while breaks down if >>there's a "continue" statement. Here's another case I just discovered: >> >>main() { >> char *foo = "outer"; >> for (;; printf(foo),exit(0)) { >> char *foo = "inner"; >> } >>} >> >>This prints "outer" (vax SVR2 compiler), though the for-while equivalence >>might lead one to expect "inner". > >I don't think the issue here is equivalence of for and while statements. >The point is that the scope of the inner 'foo' is the compound statement >which is the body of the for statement. So, quite rightly, the 'foo' >given as the argument to printf in the third expression of the for statement >refers to the most closely nested declaration of 'foo' -- the body of the >for statement is one block level higher and is not visible at this point. That was my first thought as well, but both K&R and the proposed ANSI C standard define the "for" loop as follows: for (expression-1 ; expression-2 ; expression-3) statement is equivalent to expression-1; while (expression-2) { statement expression-3; } which to me says that the example should have printed "inner".
gt6294b@gitpyr.UUCP (SCHEUTZOW,MICHAEL J) (09/03/86)
> >It's well known that the equivalence between for and while breaks down if > >there's a "continue" statement. Here's another case I just discovered: > > > >main() { > > char *foo = "outer"; > > for (;; printf(foo),exit(0)) { > > char *foo = "inner"; > > } > >} > > > >This prints "outer" (vax SVR2 compiler), though the for-while equivalence > >might lead one to expect "inner". > > The point is that the scope of the inner 'foo' is the compound statement > which is the body of the for statement. So, quite rightly... > > Kenneth R. Ballou ...!ucbvax!brahms!ballou It took me a few minutes to figure out what Ken was saying, and he is quite right. The above is equivalent to: main() { char *foo = "outer"; for (;;) { { char *foo = "inner"; /* note the 'char' */ } printf(foo); exit(0); } } Mike Scheutzow "I _think_ these are my opinions; Georgia Tech let me ask my boss..." gt6294b@gitpyr.uucp
operator@pogo.UUCP (Vax Operators) (09/04/86)
In article <570@copper.UUCP> mikeb@copper.UUCP (Mike Beckerman) writes: >In article <15525@ucbvax.BERKELEY.EDU> ballou@brahms.UUCP (Kenneth R. Ballou) writes: >>In article <86900030@haddock> karl@haddock writes: >>> >>>main() { >>> char *foo = "outer"; >>> for (;; printf(foo),exit(0)) { >>> char *foo = "inner"; >>> } >>>} >>> >>>This prints "outer" (vax SVR2 compiler), though the for-while equivalence >>>might lead one to expect "inner". >> >>I don't think the issue here is equivalence of for and while statements. >>The point is that the scope of the inner 'foo' is the compound statement ^^^^^^^^ >>which is the body of the for statement. So, quite rightly, the 'foo' >>given as the argument to printf in the third expression of the for statement >>refers to the most closely nested declaration of 'foo' -- the body of the >>for statement is one block level higher and is not visible at this point. ^^^^^^^^^^^^^^^^^^ > >That was my first thought as well, but both K&R and the proposed ANSI C standard >define the "for" loop as follows: > > for (expression-1 ; expression-2 ; expression-3) statement > > is equivalent to > > expression-1; > while (expression-2) { > statement > expression-3; > } > >which to me says that the example should have printed "inner". I think the mistake being made here is a confusion with scope. Yes, that's the definition of while and for, but look carefully at the definition for 'while': it has { statement } (brackets surrounding the statement) after the conditional, while the for has no brackets. Therefore, the correct translation of your for loop into a while loop is as follows: main() { char *foo = "outer"; while (TRUE) { { char *foo = "inner"; } printf(foo); exit(0) } } The for loop execution order is /* for (exp1; exp2; exp3) statement; */ exp1; <=> ; exp2; <=> ; statement; <=> { char *foo = "inner" } exp3; <=> printf(foo); exit(0); The 'char *foo = "inner"' disappears when the deeper scope gets popped, therefore the foo that gets printed is still "outer". Shannon Nelson "Where there is a will, there's lot's of relatives...'
brett@wjvax.UUCP (Brett Galloway) (09/04/86)
In article <86900030@haddock> version B 2.10.3 4.3bsd-beta 6/6/85; site wjvax.wjvax.UUCP wjvax!qubix!saber!sun!decwrl!pyramid!hplabs!qantel!lll-lcc!lll-crg!nike!think!ima!haddock!karl karl@haddock writes: > >It's well known that the equivalence between for and while breaks down if >there's a "continue" statement. Here's another case I just discovered: > >main() { > char *foo = "outer"; > for (;; printf(foo),exit(0)) { > char *foo = "inner"; > } >} > >This prints "outer" (vax SVR2 compiler), though the for-while equivalence >might lead one to expect "inner". > I don't understand why. The value "inner" is associated with the variable foo with scope inside the for loop (within the {}'s). The value "outer" is associated with the variable foo with scope outside the for loop (outside the {}'s). The printf(foo) is outside the for loop scope, so it should print "outer". -- ------------- Brett Galloway {pesnta,twg,ios,qubix,turtlevax,tymix,vecpyr,certes,isi}!wjvax!brett
dant@tekla.UUCP (Dan Tilque) (09/05/86)
From: mikeb@copper.UUCP (Mike Beckerman) >In article <15525@ucbvax.BERKELEY.EDU> ballou@brahms.UUCP (Kenneth R. Ballou) writes: >>In article <86900030@haddock> karl@haddock writes: >>> >>>It's well known that the equivalence between for and while breaks down if >>>there's a "continue" statement. Here's another case I just discovered: >>> >>>main() { >>> char *foo = "outer"; >>> for (;; printf(foo),exit(0)) { >>> char *foo = "inner"; >>> } >>>} >>> >>>This prints "outer" (vax SVR2 compiler), though the for-while equivalence >>>might lead one to expect "inner". >> >>I don't think the issue here is equivalence of for and while statements. >>The point is that the scope of the inner 'foo' is the compound statement >>which is the body of the for statement. So, quite rightly, the 'foo' >>given as the argument to printf in the third expression of the for statement >>refers to the most closely nested declaration of 'foo' -- the body of the >>for statement is one block level higher and is not visible at this point. > >That was my first thought as well, but both K&R and the proposed ANSI C standard >define the "for" loop as follows: > > for (expression-1 ; expression-2 ; expression-3) statement > > is equivalent to > > expression-1; > while (expression-2) { > statement > expression-3; > } > >which to me says that the example should have printed "inner". > Ken Ballou is correct, and the equivalence above is correct. The equivalence of the first example is this: main() { char *foo = "outer"; while () { { char *foo = "inner"; } printf(foo),exit(0)); } } The *foo = "inner" applies only within the inner braces (which delineate the statement). The printf(foo) goes outside those braces. Dan Tilque UUCP: tektronix!dadla!dant CSnet: dant%dadla@tektronix ARPAnet: dant%dadla%tektronix@csnet-relay Mass extinction; it's not just for dinosaurs anymore.
karl@haddock (09/06/86)
pogo!operator (Shannon Nelson) writes: >... The correct translation of your for loop into a while loop is: >main() { > char *foo = "outer"; > while (TRUE) { > { char *foo = "inner"; } > printf(foo); > exit(0); > } >} Oops. You're right; I forgot about the extra braces. But as long as we're on the subject, shouldn't the general whilified for be written "{ e1; while (e2) { statement e3; } }", with the extra pair of braces surrounding the whole mess? (Consider "if (e0) for (e1; e2; e3) statement".) Karl W. Z. Heuer (ima!haddock!karl; karl@haddock.isc.com), The Walking Lint