Path: utzoo!attcan!uunet!cs.utexas.edu!sun-barr!newstop!exodus!morocco.Eng.Sun.COM!landauer From: landauer@morocco.Eng.Sun.COM (Doug Landauer) Newsgroups: comp.lang.c++ Subject: Re: FORever Summary: Style suggestion: Always put extra braces around "for"s. Keywords: auto, break, case, catch, char, class, ... :-) Message-ID: <1070@exodus.Eng.Sun.COM> Date: 30 Sep 90 01:17:26 GMT References: <1990Sep27.150948.9109@sco.COM> <212@dumbcat.sf.ca.us> Sender: news@exodus.Eng.Sun.COM Organization: Sun Microsystems, Mt. View, Ca. Lines: 109 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."