ron@sco.COM (Ron Irvine) (09/28/90)
BEWARE there is a major problem with C++'s "for" statement. main() { for (int i=10; i<13;) { for (int i=0; i<3; ++i) ; // stuff ++i; } } Cfront accepts this code and compiles without warning. The resulting code is totally unexpected! The program loops forever?!! I realize the problem is that cfront does not end the scope of the inners loop's "i" until the end of the outer loop, thus the "++i;" statement actually increments the inner loops "i" whos scope is the outer loop. And I did not "redeclare" "i" in the outer loop since the outer "i"'s scope is outside the outer loop. This is a bad joke for a language that is designed for the 90's. The scope of a variable in a "for-init-statement" MUST end at the end of the "for" statement. Lets change the definition of the language NOW before we inflict horrendous pain on C++ programmers.
landauer@morocco.Eng.Sun.COM (Doug Landauer) (09/30/90)
ron> BEWARE there is a major problem with C++'s "for" statement. ron> ron> main() { ron> for (int i=10; i<13;) { ron> for (int i=0; i<3; ++i) ron> ; // stuff ron> ++i; ron> } ron> } It looks even worse than this if you put in the braces that the inner "for" should have had: main() { for (int i=10; i<13;) { for (int i=0; i<3; ++i) { ; // stuff } ++i; } } That is, now the "++i;" is outside of the inner for's braces, and looks (to the C programmer's eye) even less a part of it than in your example, but it still refers to the inner for's "i". ron> Let's change the definition of ron> the language NOW before we inflict horrendous pain on C++ programmers. Too late. To change it now would indeed inflict too much pain on programmers who have existing C++ code that depends on this decision. My suggestion is to adhere to a C++-Style-Guide rule that says: ***Whenever*** you declare a variable within a "for" loop, surround the for loop with an extra set of braces, starting before the "for" keyword. Thus, I would have written your example like so: main() { {for (int i=10; i<13;) { {for (int i=0; i<3; ++i) { ; // stuff }} ++i; }} } This also improves the situation in those cases where you have two non-nested loops, both using the same variable: main() { {for (int i=10; i<13; ++i) { ; // Do some stuff to 3 somethings }} // Do other stuff {for (int i=10; i<13; ++i) { ; // Do some stuff to 3 other somethings }} } Now, you no longer get the "two declarations of i" error message when you copy a for loop to another part of the same function, and you get a visually distinct way of showing that the "i" in this for loop really belongs only inside the loop. When you really do want to use "i" after the loop is over, *then* you can break the double-brace apart, and of course you would then give the loop an extra indentation level. marc> Do you really want to break all the existing code that does something like marc> marc> for (int i=10; i<13; ++i) { marc> if (x[i] == magicValue) { marc> break; marc> } marc> } marc> if (i >= 13) { marc> // we didn't find magicValue marc> } Under the proposed rule, this becomes { // contain the scope of "i" for( int i=10; i < 13; ++i) { if( x[i] == magicValue) { break; } } if( i >= 13 { // we didn't find magicValue } } // end scope of "i" marc> Lots of C code uses this. No C code uses this; it's not C code. The ANSI C standard won't let you declare a variable within that () part of a "for" loop, and I've never seen any C compiler which would allow it, either. However, lots of C++ code does use this. [ You have to, if you write any member functions. :-) ] marc> I assume (which will probably get me into marc> trouble) that C++ programmers will want to do the same thing. No trouble here -- C++ programmers will want to do almost any damn thing that cfront will allow them to do. Worse, C++ programmers still want to do any damn thing that cfront has ever allowed them to do. (... and people in hell want icewater ...) -- Doug Landauer - Sun Microsystems, Inc. - Languages - landauer@eng.sun.com Matt Groening on C++: "Our language is one great salad."
ark@alice.att.com (Andrew Koenig) (10/01/90)
In article <212@dumbcat.sf.ca.us>, marc@dumbcat.sf.ca.us (Marco S Hyman) writes: > Do you really want to break all the existing code that does something like > for (int i=10; i<13; ++i) { > if (x[i] == magicValue) { > break; > } > } > if (i >= 13) { > // we didn't find magicValue > } > Lots of C code uses this. I hope not -- it isn't legal C. C does not allow variables to be declared in `for' statements; instead one must write something like this: int i; for (i=10; i<13; ++i) { if (x[i] == magicValue) { break; } } if (i >= 13) { // we didn't find magicValue } The meaning of such things would not be affected by any change in the scope of C++ variables declared in `for' statements. -- --Andrew Koenig ark@europa.att.com
graham@convex.com (Marv Graham) (10/02/90)
In article <1990Sep27.150948.9109@sco.COM> ron@sco.COM (Ron Irvine) writes: > >BEWARE there is a major problem with C++'s "for" statement. > >main() { > for (int i=10; i<13;) { > for (int i=0; i<3; ++i) > ; // stuff > ++i; > } >} > >Cfront accepts this code and compiles without warning. >The resulting code is totally unexpected! >The program loops forever?!! > >I realize the problem is that cfront does not end the >scope of the inners loop's "i" until the end of the >outer loop, thus the "++i;" statement actually increments >the inner loops "i" whos scope is the outer loop. And I >did not "redeclare" "i" in the outer loop since the outer >"i"'s scope is outside the outer loop. > >This is a bad joke for a language that is designed for the 90's. >The scope of a variable in a "for-init-statement" MUST end >at the end of the "for" statement. Lets change the definition of >the language NOW before we inflict horrendous pain on C++ programmers. In my opinion, the PROBLEM is using a badly defined new toy instead of writing main() { int i ; // this really belongs here for (i=10; i<13;) { { // this really is needed here int i ; // and this really belongs here for (i=0; i<3; ++i) ; // stuff } // this makes the next ++i refer to the outer one ++i; } } If you say what you mean, you get what you want. What we should really do is make the nested definitions illegal (again)! But, if you had just a little common sense, you would write main() { int i ; for (i=10; i<13;) { int j ; // what, not "i" again?? for (j=0; j<3; ++j) ; // stuff ++i; } } Can't you really think of a name for a for loop index besides "i"? Marv Graham; Convex Computer Corp. {uunet,sun,uiucdcs,allegra}!convex!graham
cory@howtek.UUCP (Cory Kempf) (10/03/90)
In article <1990Sep27.150948.9109@sco.COM> ron@sco.COM (Ron Irvine) writes: > >BEWARE there is a major problem with C++'s "for" statement. No, the for statement works as it should... >main() { > for (int i=10; i<13;) { > for (int i=0; i<3; ++i) > ; // stuff > ++i; > } >} > >Cfront accepts this code and compiles without warning. >The resulting code is totally unexpected! hardly. see below. I will try to refrain from comment about poor programming style. >The program loops forever?!! Of course it loops forever! That is what you told it to do. Think about how that structure would be implimented in C: main() { int i; for(i=10;i<13;) { int i; // hides previous i for (i=0; i<3; ++i) ; // stuff ++i; // note the scope of i } } The result is, I believe, obvious. >I realize the problem is that cfront does not end the >scope of the inners loop's "i" until the end of the >outer loop, thus the "++i;" statement actually increments >the inner loops "i" whos scope is the outer loop. This is a documented behaviour by the way. +C
marc@dumbcat.sf.ca.us (Marco S Hyman) (10/04/90)
In article <11410@alice.att.com> ark@alice.att.com (Andrew Koenig) writes: In article <212@dumbcat.sf.ca.us> I wrote: > Do you really want to break all the existing code that does something > like > for (int i=10; i<13; ++i) { > if (x[i] == magicValue) { > break; > } > } > if (i >= 13) { > // we didn't find magicValue > } Thanks to Andrew (and the others who send e-mail) for pointing out my stupid slip -- it is not and never has been C code. But the question still remains -- does the C++ community favor dissallowing the above code? I've seen this style used in C++ programs. (I didn't like it when I saw it, either). // marc -- // marc@dumbcat.sf.ca.us // {ames,decwrl,sun}!pacbell!dumbcat!marc
schmidt@indetech.com (Douglas C. Schmidt) (10/11/90)
[ED note: This is posted on behalf of Jim Roskind]
----------------------------------------
In article <1990Sep27.150948.9109@sco.COM> ron@sco.COM (Ron Irvine) writes:
ron> BEWARE there is a major problem with C++'s "for" statement.
ron>
ron> main() {
ron> for (int i=10; i<13;) {
ron> for (int i=0; i<3; ++i)
ron> ; // stuff
ron> ++i;
ron> }
ron> }
ron>
ron> ...
ron>
ron> This is a bad joke for a language that is designed for the 90's.
ron> The scope of a variable in a "for-init-statement" MUST end
ron> at the end of the "for" statement. Lets change the definition of
ron> the language NOW before we inflict horrendous pain on C++ programmers.
Response From: marc@dumbcat.sf.ca.us (Marco S Hyman)
Marco>
Marco> Do you really want to break all the existing code that does something like
Marco>
Marco> for (int i=10; i<13; ++i) {
^^^^^^^^
Marco> if (x[i] == magicValue) {
Marco> break;
Marco> }
Marco> }
Marco> if (i >= 13) {
Marco> // we didn't find magicValue
Marco> }
Marco>
Marco> Lots of C code uses this. I assume (which will probably get me into
^^^
Marco> trouble) that C++ programmers will want to do the same thing.
Marco>
Actually, since C code does *not* allow declarations in the middle of
a "for" statement, this adjustment does *not* seem to break any "old C
code". When C++ programmers "want to do the same thing", I think they
would be well advised to clearly locate the declaration of the
iteration variable at the scope in which they intend to use the
variable (i.e., declare "i" before the "for" statement if the intent
is to continue using it after the "for" statement). This approach is
actually what C programmers have always been doing :-).
I am aware that current semantic rules (re: E&S and cfront) support
the odd behavior wherein variables declared in the for statement are
"exported" to the enclosing scope. From my view, this would appear to
be a "bug" in cfront that has grown to be gospel in E&S. I can only
hope that enough programmers will take it upon themselves to avoid use
of such arguable semantic decisions, with the belief that the decision
*might* some day be changed. If enough programmers take this
enlightened view, it may be possible to make the transition, but
otherwise C++ will slowly be saddled with more than the heritage and
compatibility with C, it must also forever support its initial
decisions (accidents?).
I personally don't think that any of the little quirks in C++ (this is
only one) can, in and of themselves individually, damage the language.
I tend to wonder when the summation of the many quirks might actually
end up hindering the language and its use/implementation.
I agree with Ron Irvine, and I would like to see the for statement
limit the scope of declared variables to its own "for statement
scope". I figure every little bit of improvement helps the language,
but the questions of compatibility haunt me, as the trade-off between
good language design and "existing" code are beyond me.
--
Jim Roskind- Author of a YACCable C++ grammar
Independent Consultant
(407)729-4348 or (617)577-9813 x5570
jar@hq.ileaf.com or ...!uunet!leafusa!jar
--
____*_ Douglas C. Schmidt schmidt@indetech.com
\ / / Independence Technologies {sun,sharkey,pacbell}!indetech!schmidt
\/ / 42705 Lawrence Place FAX: 415 438-2034
\/ Fremont, CA 94538 Voice: 415 438-2023
daves@ex.heurikon.com (Dave Scidmore) (10/17/90)
In article <1990Sep27.150948.9109@sco.COM> ron@sco.COM (Ron Irvine) writes: ron> BEWARE there is a major problem with C++'s "for" statement. ron> ron> main() { ron> for (int i=10; i<13;) { ron> for (int i=0; i<3; ++i) ron> ; // stuff ron> ++i; ron> } ron> } ron> ... ron> This is a bad joke for a language that is designed for the 90's. ron> The scope of a variable in a "for-init-statement" MUST end ron> at the end of the "for" statement. Lets change the definition of ron> the language NOW before we inflict horrendous pain on C++ programmers. Response From: marc@dumbcat.sf.ca.us (Marco S Hyman) Marco> Marco> Do you really want to break all the existing code that does something like Marco> Marco> for (int i=10; i<13; ++i) { ^^^^^^^^ Marco> if (x[i] == magicValue) { Marco> break; Marco> } Marco> } Marco> if (i >= 13) { Marco> // we didn't find magicValue Marco> } Marco> Marco> Lots of C code uses this. I assume (which will probably get me into Marco> trouble) that C++ programmers will want to do the same thing. Marco> > Actually, since C code does *not* allow declarations in the middle of > a "for" statement, this adjustment does *not* seem to break any "old C > code". My assumption would be that he wished to say break existing C++ code and accidentaly wrote existing C code. > I am aware that current semantic rules (re: E&S and cfront) support > the odd behavior wherein variables declared in the for statement are > "exported" to the enclosing scope. From my view, this would appear to > be a "bug" in cfront that has grown to be gospel in E&S. Since this "bug", as you call it, also appears in "The C++ Programming Language" semantic rules, and since the language had been in use at AT&T for some time before either book was published I can only assume it was a carefully considered decision and not a bug. Faced with the same decision I have to admit that I would have made the same choice. To make the variable a part of the outer scope allows it to be used after the end of the "for" statement while restricting it to the inner scope only prevent problems where bad programming practices are used, i.e. multiple variables with the same name in different scopes. On top of this the variable actualy appears outside the curly braces which delimit the inner scope, making it intuitively obvious that it is not a part of that scope. If curly braces introduce a new scope, as the semantic rules for C++ state then the "for" loop variable must be part of the outer scope and not the inner one. > I personally don't think that any of the little quirks in C++ (this is > only one) can, in and of themselves individually, damage the language. It is poor form to use unnamed "quirks" as an argument. Give us examples. > I agree with Ron Irvine, and I would like to see the for statement > limit the scope of declared variables to its own "for statement > scope". I dissagree. I have had no problem dealing with this rule and understanding its consequences from the first time I read about it. I also would submit that the current scope rules provided by E&S are consistent and that the rule you are proposing is not. -- Dave Scidmore, Heurikon Corp. dave.scidmore@heurikon.com