Topic: Scope of Names in a FOR statement?
Author: brahms@mindspring.com (Stan Brown)
Date: 1999/03/29 Raw View
[This followup was also e-mailed to the cited author.]
In this next-to-last year of the millennium, sbm404@aol.com (SBM404)
wrote in comp.std.c++:
>The December 1996 Working Paper on the C++ standard states -
>If the for-init-statement is a declaration, the scope of the name(s)
>declared extends to the end of the for-statement
>
>In contrast, a 1997 text by Dale,Weems, Headingtin on C++ states -
> for (int i =1; i <= 20; i++)
> cout << "Hi" << endl;
> for (int i =1; i <= 20; i++)
> cout << "Ed" << endl; // Error - i already declared.
The first is correct. (See Stroustrup 3rd edition, page 825; the standard
at subclause 6.5.3/3 uses the same words you quoted.) DWH are wrong -- as
are some current compilers, including both versions 5 and 6 of the Brand
M compiler.
Unless you've verified that your compiler does the right thing, you want
to write code that will be correct both when compiled by a conforming
compiler and when compiled by yours. (Maybe you want to do that even if
your compiler is correct, in case your code gets ported to a
nonconforming compiler.) The safest way to avoid the problem is with a
little discipline: use a different variable in each for loop where you
need to have a variable, but (this is the discipline part) make sure that
you don't then refer to that variable outside the for loop.
Of course, if you actually need the variable after the end of the for
loop, you should declare it before the "for" even if your compiler
doesn't force you to.
--
Stan Brown, Oak Road Systems, Cleveland, Ohio, USA
http://www.mindspring.com/~brahms/
My reply address is correct as is. The courtesy of providing a correct
reply address is more important to me than time spent deleting spam.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/03/29 Raw View
sbm404@aol.com (SBM404) writes:
>The December 1996 Working Paper on the C++ standard states -
>If the for-init-statement is a declaration, the scope of the name(s)
>declared extends to the end of the for-statement. [Example:
> int i = 42;
> int a[10];
> for (int i = 0; i < 10; i++)
> a[i] = i;
> int j = i; // j = 42
> --end example]
The final standard has the same text and the same example in
section 6.5.3.
>In contrast, a 1997 text by Dale,Weems, Headingtin on C++ states -
>The scope extends to the end of the block surrounding the FOR statement.
>An example given is
> for (int i =1; i <= 20; i++)
> cout << "Hi" << endl;
> for (int i =1; i <= 20; i++)
> cout << "Ed" << endl; // Error - i already declared.
That was the rule in the ARM. The rule change was first made in a
draft of the standard in about 1993.
Until quite recently, however, not many compilers implemented the
changed rule.
--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 1999/03/30 Raw View
In article <MPG.1168b99c39434f949897d1@news.mindspring.com>,
brahms@mindspring.com (Stan Brown) wrote:
> [This followup was also e-mailed to the cited author.]
[snip]
> The first is correct. (See Stroustrup 3rd edition, page 825; the standard
> at subclause 6.5.3/3 uses the same words you quoted.) DWH are wrong -- as
> are some current compilers, including both versions 5 and 6 of the Brand
> M compiler.
A workaround commonly proposed (I haven't tried it myself) for non-conforming
compilers is:
#define for if (0) {} else for
This puts any variables declared in the for-init-statement inside the scope of
the 'else' clause. Note that it must not be:
#define for if (1) for
because that would mess up if/else matching, for example:
if(condition1)
for (/*...*/)
/* some useful statement goes here in place of the comment */
else
/* another useful statement goes here in place of the comment */
If you use the second macro, the 'else' would match up with the 'if' inside
the macro - definitely not what you want.
Jim
Note to recruitment agencies: I will not refer my friends or colleagues
to you nor do I want to use your services to find me a job. I stop
reading unsolicited email as soon as I determine it is job-recruitment
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "AllanW {formerly AllanW@my-dejanews.com}" <allan_w@my-dejanews.com>
Date: 1999/03/30 Raw View
In article <MPG.1168b99c39434f949897d1@news.mindspring.com>,
brahms@mindspring.com (Stan Brown) wrote:
> Unless you've verified that your compiler does the right thing, you want
> to write code that will be correct both when compiled by a conforming
> compiler and when compiled by yours. (Maybe you want to do that even if
> your compiler is correct, in case your code gets ported to a
> nonconforming compiler.) The safest way to avoid the problem is with a
> little discipline: use a different variable in each for loop where you
> need to have a variable, but (this is the discipline part) make sure that
> you don't then refer to that variable outside the for loop.
Either rule is easy to live with. The problem is that you might
use a compiler with one rule today, and the other rule tomorrow.
When switching compilers (or versions), usually most of the
places that break are identified by the compiler. The real problem
is the "silent" changes, such as this one:
int i=42;
void x() {
int a[10];
for (int i=0; i < 10; i++)
a[i] = i;
return i;
}
This code compiles without warnings on both types of compilers.
(I suppose some theoretical compiler could warn "a[] is
initialized but not used" but I doubt that very many are this
smart.) But does x() return 42, or 10? Identifying these silent
changes is the really hard part.
Fortunately, once you've identified such code, dealing with it
is usually quite simple. To make variables live beyond the loop,
simply pull initialization out. Change
for (int i=0; i < 10; i++)
a[i] = i;
into
int i=0;
for (; i < 10; i++)
a[i] = i;
To make sure that variables have their own scope, simply add
redundant braces around the for statement and body. Change
for (int i=0; i < 10; i++)
a[i] = i;
into
{ for (int i=0; i < 10; i++)
a[i] = i; }
----
Allan_W@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "AllanW {formerly AllanW@my-dejanews.com}" <allan_w@my-dejanews.com>
Date: 1999/03/30 Raw View
In article <19990328002414.00337.00001483@ng-cc1.aol.com>,
sbm404@aol.com (SBM404) wrote:
>
> The December 1996 Working Paper on the C++ standard states -
> If the for-init-statement is a declaration, the scope of the name(s)
> declared extends to the end of the for-statement. [Example:
> int i = 42;
> int a[10];
> for (int i = 0; i < 10; i++)
> a[i] = i;
> int j = i; // j = 42
> --end example]
This is correct, in the standard at 6.5.3 p3.
> In contrast, a 1997 text by Dale,Weems, Headingtin on C++ states -
> The scope extends to the end of the block surrounding the FOR statement.
Obviously written to an earlier draft or to the ARM.
----
Allan_W@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/03/30 Raw View
Jim Hyslop <jim.hyslop@leitch.com> writes:
>In article <MPG.1168b99c39434f949897d1@news.mindspring.com>,
> brahms@mindspring.com (Stan Brown) wrote:
>> [This followup was also e-mailed to the cited author.]
>[snip]
>> The first is correct. (See Stroustrup 3rd edition, page 825; the standard
>> at subclause 6.5.3/3 uses the same words you quoted.) DWH are wrong -- as
>> are some current compilers, including both versions 5 and 6 of the Brand
>> M compiler.
>A workaround commonly proposed (I haven't tried it myself) for non-conforming
>compilers is:
>#define for if (0) {} else for
Altering the meaning of keywords is evil.
The obvious, simple, correct workaround is to move the declaration
out of the for-loop:
int i;
for(i=0; i<N; ++i) { ... }
Such code has the same meaning with every compiler, and there
are no hidden traps for the programmer who naively thinks
"for" means "for".
--
Steve Clamage, stephen.clamage@sun.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Bruce Visscher <bvisscher@mindspring.com>
Date: 1999/03/31 Raw View
Steve Clamage wrote:
> Jim Hyslop <jim.hyslop@leitch.com> writes:
>
> >In article <MPG.1168b99c39434f949897d1@news.mindspring.com>,
> > brahms@mindspring.com (Stan Brown) wrote:
> >> [This followup was also e-mailed to the cited author.]
> >[snip]
> >> The first is correct. (See Stroustrup 3rd edition, page 825; the standard
> >> at subclause 6.5.3/3 uses the same words you quoted.) DWH are wrong -- as
> >> are some current compilers, including both versions 5 and 6 of the Brand
> >> M compiler.
> >A workaround commonly proposed (I haven't tried it myself) for non-conforming
> >compilers is:
>
> >#define for if (0) {} else for
>
> Altering the meaning of keywords is evil.
>
> The obvious, simple, correct workaround is to move the declaration
> out of the for-loop:
>
> int i;
> for(i=0; i<N; ++i) { ... }
The workaround I've taken to lately is:
{ // redundant scope for broken compilers
for(int i=0; i<N; ++i) {...}
}
This also has the same meaning with an old or new compiler, but the scope of the
variable i more closely corresponds to that of the for loop.
It doesn't address the subtle changes alluded to by AllenW in another post, but I
think those situations should be (hopefully) rare.
Bruce
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "AllanW {formerly AllanW@my-dejanews.com}" <allan_w@my-dejanews.com>
Date: 1999/03/31 Raw View
> Jim Hyslop <jim.hyslop@leitch.com> writes:
> >#define for if (0) {} else for
In article <7drh0q$60r$1@engnews1.eng.sun.com>,
clamage@eng.sun.com (Steve Clamage) wrote:
> Altering the meaning of keywords is evil.
A good rule of thumb, and you'll find few who disagree. But you can take
this too far. Using a macro to fix a "broken" (or old) implementation of
C++ isn't evil, so long as it's handled cautiously -- be sure to isolate
the #define so it can be elided when needed, and be sure to test test
test the result (because of the dangers of hidden semantics changes).
----
Allan_W@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Ron Natalie <ron@sensor.com>
Date: 1999/04/01 Raw View
Steve Clamage wrote:
>
>
> >#define for if (0) {} else for
>
> Altering the meaning of keywords is evil.
This doesn't alter the maning of the keyword. It "fixes"
the keyword in a broken compiler to bring it in line with a
standard implemetation.
>
> The obvious, simple, correct workaround is to move the declaration
> out of the for-loop:
>
> int i;
> for(i=0; i<N; ++i) { ... }
But not the same as the original code. It will clobber
other independent i variables in the outer scope. You
need to wrap braces around it to be equivelent.
>
> Such code has the same meaning with every compiler, and there
> are no hidden traps for the programmer who naively thinks
> "for" means "for".
>
But the trap has been sprung already. For doesn't mean
what the standard for means in compilers who scope the
variables wrong.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbm404@aol.com (SBM404)
Date: 1999/03/29 Raw View
The December 1996 Working Paper on the C++ standard states -
If the for-init-statement is a declaration, the scope of the name(s)
declared extends to the end of the for-statement. [Example:
int i = 42;
int a[10];
for (int i = 0; i < 10; i++)
a[i] = i;
int j = i; // j = 42
--end example]
In contrast, a 1997 text by Dale,Weems, Headingtin on C++ states -
The scope extends to the end of the block surrounding the FOR statement.
An example given is
for (int i =1; i <= 20; i++)
cout << "Hi" << endl;
for (int i =1; i <= 20; i++)
cout << "Ed" << endl; // Error - i already declared.
Which of these is now correct in the final approved version of the C++
standard?
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]