variable scope in for loop

W

Wenjie

Hello,


We had a code review with the argument of
whether "i" is out of scope as illustrated
below:
for (int i=0; i<2004; i++)
{
doSomething(i);
}

for (i=0; i<2004; i++)
{
doSomethingElse(i);
}

Is it correct according to C++ language?
VC++6.0 works fine with above code.


Thanks and best regards,
Wenjie
 
R

Rob Williscroft

Wenjie wrote in
We had a code review with the argument of
whether "i" is out of scope as illustrated
below:
for (int i=0; i<2004; i++)
{
doSomething(i);
}

for (i=0; i<2004; i++)
{
doSomethingElse(i);
}

Is it correct according to C++ language?
Nope,

VC++6.0 works fine with above code.

Its a well known defect with this compiler, so much so that MSVC 7.1
also behaves this way by default (it has 2 option's that can remove
the defect /Za and /Zc:forScope).


Rob.
 
W

Wagner Bruna

Hello,

We had a code review with the argument of
whether "i" is out of scope as illustrated
below:
for (int i=0; i<2004; i++)
{
doSomething(i);
}

for (i=0; i<2004; i++)
{
doSomethingElse(i);
}

Is it correct according to C++ language?
VC++6.0 works fine with above code.

No, it's not correct. The scope of i ends at the end of the first
loop.

If you need VC++6 portability, a good workaround IMHO is to enclosure
the loops inside artificial blocks:

{
for (int i=0; i<2004; i++) {
doSomething(i);
}
}

{
for (int i=0; i<2004; i++) {
doSomethingElse(i);
}
}
 
D

Dietmar Kuehl

We had a code review with the argument of
whether "i" is out of scope as illustrated
below:
for (int i=0; i<2004; i++)
{
doSomething(i);
}

for (i=0; i<2004; i++)
{
doSomethingElse(i);
}

Is it correct according to C++ language?

No, it is not.
VC++6.0 works fine with above code.

Well, this compiler is not known for its standard conformance, is it? Try
one base on the EDG front-end or, better yet, verify things in the standard.
 
R

Rolf Magnus

Wagner said:
Hello,

(e-mail address removed) (Wenjie) wrote in message


No, it's not correct. The scope of i ends at the end of the first
loop.

If you need VC++6 portability, a good workaround IMHO is to enclosure
the loops inside artificial blocks:

{
for (int i=0; i<2004; i++) {
doSomething(i);
}
}

{
for (int i=0; i<2004; i++) {
doSomethingElse(i);
}
}

IIRC, another, less intrusive workaround is to

#define for if(false); else for
 
R

Ron Natalie

Wagner Bruna said:
If you need VC++6 portability, a good workaround IMHO is to enclosure
the loops inside artificial blocks:

What we do (and I know this is technically illegal, but if VC++ is going to
break the rules, we will too!):

#define for if(false);else for

It's in our master win32 config file right after disabling warning 4786!
 
P

Pete Becker

Rolf said:
IIRC, another, less intrusive workaround is to

#define for if(false); else for

An even less intrusive workaround is to move the variable declaration
outside the loop:

int i;
for (i=0; i<2004; i++)
{
doSomething(i);
}

for (i=0; i<2004; i++)
{
doSomethingElse(i);
}

Look, ma, no macros.
 
R

Ron Natalie

Pete Becker said:
An even less intrusive workaround is to move the variable declaration
outside the loop:

int i;
Actually, I find that MORE intrusive. You have to put sloppy coding
practices in your code to correct for defects in the compiler.

If you were going to do that (and eschew macros), it would be better to
rename the variable and keep it defined inside the loop.
 
P

Pete Becker

Ron said:
Actually, I find that MORE intrusive. You have to put sloppy coding
practices in your code to correct for defects in the compiler.

It's only sloppy if you treat it that way. But you often have to do
things you'd rather not in order to get around compiler limitations.
 
J

Jeff Schwab

Pete said:
An even less intrusive workaround is to move the variable declaration
outside the loop:

int i;
for (i=0; i<2004; i++)
{
doSomething(i);
}

for (i=0; i<2004; i++)
{
doSomethingElse(i);
}

Look, ma, no macros.

I certainly prefer your macroless approach, but why not initialize i
where it is defined, and save an assignment?

int i = 0;

for( ; i < 2004; ++i )
do_something( i );

for( i = 0; i < 2004; ++i )
do_something_else( i );

In production code, I tend to prefer while-loops to for-loops anyway, so
it would look something like this:

int i = 0;

while( i < 2004 )
{
do_something( i );
++i
}

i = 0;

while( i < 2004 )
{
do_something_else( i );
++i;
}

I know folks are religious about for-loops; please don't be offended if
I don't respond to criticisms about keeping loop control at the top of
the block. :)
 
P

Pete Becker

Jeff said:
I certainly prefer your macroless approach, but why not initialize i
where it is defined, and save an assignment?

Because two things that do the same thing ought to look alike.
 
J

Jeff Schwab

Pete said:
Because two things that do the same thing ought to look alike.

Maybe; that's an aesthetic preference. I don't think itt's a good
reason to delay initialization of a variable (or replace it with
assignment).

I admit that there's a nice feeling of symmetry when code is all lined
up, shiny and fixed-width. The proportional font used in TC++PL looks
pretty good, though, even when similar blocks of code are formatted in
totally different ways...
 
J

Jeff Schwab

Pete said:
No, it's about readability.

I think initialized variables properly does more for readability than
making blocks of code look alike. Just my opinion, though.
 
A

Andrey Tarasevich

Jeff said:
...
I think initialized variables properly does more for readability than
making blocks of code look alike. Just my opinion, though.
...

In my opinion, separating initialization of loop variable from the loop
itself might create more problems than delayed intialization of a variable.
 
J

Jeff Schwab

Andrey said:
In my opinion, separating initialization of loop variable from the loop
itself might create more problems than delayed intialization of a variable.

For instance?
 
P

Pete Becker

Jeff said:
I think initialized variables properly does more for readability than
making blocks of code look alike. Just my opinion, though.

Initializing variables isn't about readability, it's about limiting
risk. If you're seriously concerned that you'll use loop index when it
doesn't have a sensible value, then in addition to initializing it when
you create it you need to reset it immediately after the first loop,
just in case you refer to it before it gets reinitialized for the second
loop. But, of course, that would look really stupid. At some point you
have to think, instead of programming by cliche.
 
A

Andrey Tarasevich

Jeff said:
For instance?

For example, someone might inadvertently insert some other piece of code
between the declaration of 'i' and the first cycle. If this new code
happens to modify 'i' (let's say it is also a 'for' cycle on 'i') then
the original first cycle will start with incorrect value of 'i'.

C90-style of variable declaration is not really compatible with
"declaration is an initialization" principle.

In my opinion, it makes more sense to assign the initial value to the
variable as close as possible to the spot where the effect of this
assignment is used. In this partucular case this is achieved by placing
the 'i = 0' expression inside each 'for' statement.
 
R

Rolf Magnus

Pete said:
An even less intrusive workaround is to move the variable declaration
outside the loop:

int i;
for (i=0; i<2004; i++)
{
doSomething(i);
}

for (i=0; i<2004; i++)
{
doSomethingElse(i);
}

You consider this less intrusive? You have to use that workaround in
every function that has more than one for loop, while the macro only
needs to be defined in one single place in a header that gets included
everywhere. At the place where the for loop is, you don't need to take
care about such things anymore.
Look, ma, no macros.

So you wouldn't use that macro just for the sole sake of avoiding
macros? Or do you have any real technical reason?
 
P

Pete Becker

Rolf said:
You consider this less intrusive? You have to use that workaround in
every function that has more than one for loop

It's not a workaround. It's a way of writing portable code when you plan
to target a compiler that doesn't support for loop scoping.
So you wouldn't use that macro just for the sole sake of avoiding
macros? Or do you have any real technical reason?

Neither. Apparently you don't grasp humor.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top