variable scope in for loop

R

Rolf Magnus

Pete said:
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.

I'd not be willing to use that "way of writing code" if I don't need to.
Well, actually, I'm not using VC++ myself, but if anyone wants to port
my code to it, he either needs to change all the for loops (since I
always define the counter in the for scope, which looks cleaner to me),
or add the macro.
Neither. Apparently you don't grasp humor.

English is not my native tongue, so I might have difficulties to grasp
your humor. Anyway, what's your point then?
 
H

Howard

Rolf Magnus said:
I'd not be willing to use that "way of writing code" if I don't need to.
Well, actually, I'm not using VC++ myself, but if anyone wants to port
my code to it, he either needs to change all the for loops (since I
always define the counter in the for scope, which looks cleaner to me),
or add the macro.


English is not my native tongue, so I might have difficulties to grasp
your humor. Anyway, what's your point then?

Just an old expression used as a joke. Originally it was "look, ma, no
hands"...used when doing something like riding your bicycle without using
your hands.

I think I agree with him that I'd just as soon not use macros. No real
rechnical reason, I just don't like using them, I guess because you have to
go look up what they do, try to figure out what the result of them is after
parsing, and then they can be changed on you and you have to find everywhere
they're used and be sure those places aren't broken. Just a pain in the
arse if you ask me.

Personally, I do it like you and write them according to the standard, with
i declared within each for loop. Then, when I port to VC++ 6.0 (which I
often do), I change the code that fails to compile and use a single
declaration for i before the first loop.

But I never use macros. (Templates are a pain in the ass to figure out
sometimes, too, but their power is to great to ignore! :))

-Howard
 
J

Jack Klein

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 );

Because somebody maintaining your code some day, somebody else or even
you, will rearrange the loops or stick another one or another use for
'i' between the definition with initialization and the first for loop.
Then a perhaps strange and hard-to-find defect will be born.

The loop should perform its own initialization.
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. :)

Nothing against while loops, I use them myself quite frequently, or
even do ... while loops, more often than most.

But I don't like an important condition of the loop separated from the
control statement itself, both for conceptual reasons and also for the
above mentioned maintenance problem. If someone, someday, puts
something between the initialization or the assignment and the
corresponding loop, bang!

In your particular example, I would use the for loop because it allows
setting the initial value of the control variable, a necessary
requirement of the loop, to appear in the loop control logic.
 
G

Gary Labowitz

Nothing against while loops, I use them myself quite frequently, or
even do ... while loops, more often than most.

But I don't like an important condition of the loop separated from the
control statement itself, both for conceptual reasons and also for the
above mentioned maintenance problem. If someone, someday, puts
something between the initialization or the assignment and the
corresponding loop, bang!

In your particular example, I would use the for loop because it allows
setting the initial value of the control variable, a necessary
requirement of the loop, to appear in the loop control logic.

We fought this problem of loop control for years in various shops and the
only bulletproof method we ever decided on was to use differently named loop
control variables in any block. While i, j, k seem traditional, presumably
left over from FORTRAN, it even makes for self-documenting code to use names
that mean something in the process being coded. Loop control variables like
addressVectorItem for referencing an address in a Vector of addresses I feel
is better than just i. Long, fluffy names, that's the ticket!
 
E

E. Mark Ping

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

You're saying that declaring the variable outside the loop is more
intrusive than using a macro to effectively redefine a language
keyword?

I find this baffling.
 
R

Ron Natalie

E. Mark Ping said:
You're saying that declaring the variable outside the loop is more
intrusive than using a macro to effectively redefine a language
keyword?

I find this baffling.

I don't. The only thing I'm "redefining" here is making the keyword
behave like the language standard says it should. I pointed out that
it is technically wrong, but so is Microsoft, and I'd rather have standard
compliant code rather than Microsoft compliant code, we're portable
to platforms other than Windows.

By making this change, once, with the approval of our design team
and putting it in a controlled place, it gets around a zillion Microsoft
specific hacks that involve bad coding practices of leaving variables
uninitialized or sitting around outside the scope they are used in.

I'm not recommending the willy nilly redefining of keywords, but in
this case making the tested, controlled, one line change IS LESS
INTRUSIVE, than having to break standard-conforming code everywhere
else it appears OR adding bad programming practices because the
compiler is busted.
 
H

Howard

Ron Natalie said:
By making this change, once, with the approval of our design team
and putting it in a controlled place, it gets around a zillion Microsoft
specific hacks that involve bad coding practices of leaving variables
uninitialized or sitting around outside the scope they are used in.

I'm curious why you call it "bad coding practice" to have a single variable
used more than once. I understand that i is in this case just an integer,
and there's no logical reason why it *shouldn't* be declared in each for
loop construct, but what does it hurt to declare it once and use it multiple
times?

Imagine if you had, instead of an integer being used in multiple for loops,
some more complex object being used in multiple blocks of code within one
function. The overhead of constructing the object multiple times now can
outweigh the desired practice of declaring it within each block.

Personally, I prefer to declare i within each loop construct, and then
change that specific piece of code when I port to VC++. If I forget to
change it, the compiler tells me.

Provided that you do not rely on the value of i between or at the start of
any block, but instead assign it a value in the initializer portion of each
for loop, I fail to see where any harm can come from declaring it once and
using it multiple times. (And in the bad old days when I needed every byte
of memory I could get my grubby little hands on, it was practically a
*requirement* that I do it that way!)

-Howard
 
R

Ron Natalie

Howard said:
I'm curious why you call it "bad coding practice" to have a single variable
used more than once. I understand that i is in this case just an integer,
and there's no logical reason why it *shouldn't* be declared in each for
loop construct, but what does it hurt to declare it once and use it multiple
times?

Because why permit it to be inadvertantly used in expressions in between
the unrelated loops you're stuck using it in. Terribly non-structured.
Imagine if you had, instead of an integer being used in multiple for loops,
some more complex object being used in multiple blocks of code within one
function. The overhead of constructing the object multiple times now can
outweigh the desired practice of declaring it within each block

If it were not something that made sense to be shared, it should be destroyed.
But you're inventing issues, by default variables should be defined in the smallest
scope that encompasses their use. THIS IS JUST PLAIN GOOD C++ DESIGN.
Having to thwart that because Microsnot can't get it right isn't a good reason
to chage the design rules.
Personally, I prefer to declare i within each loop construct, and then
change that specific piece of code when I port to VC++. If I forget to
change it, the compiler tells me.

If you do what I suggested, you don't have to go bastardizing your code
just because you have the misfortune of using Microsnot's compiler.
 
J

Jeff Schwab

Ron Natalie wrote:

By making this change, once, with the approval of our design team
and putting it in a controlled place, it gets around a zillion Microsoft
specific hacks that involve bad coding practices of leaving variables
uninitialized or sitting around outside the scope they are used in.

I'm not recommending the willy nilly redefining of keywords, but in
this case making the tested, controlled, one line change IS LESS
INTRUSIVE, than having to break standard-conforming code everywhere
else it appears OR adding bad programming practices because the
compiler is busted.

Of course, you'll have to include the macro in each source file using a
"for" loop. You'll need to be careful not to include before any of the
MS headers, too, to avoid breaking them.
 
R

Rolf Magnus

Howard said:
I'm curious why you call it "bad coding practice" to have a single
variable
used more than once. I understand that i is in this case just an
integer, and there's no logical reason why it *shouldn't* be declared
in each for loop construct, but what does it hurt to declare it once
and use it multiple times?

IMHO, doing that doesn't hurt so much, but it does hurt to be forced to
do it. I think it's cleaner to have a loop counter defined in the loop
instead of before, and I like to be able to do that.
OTOH, how does the proposed macro hurt?
Imagine if you had, instead of an integer being used in multiple for
loops, some more complex object being used in multiple blocks of code
within one function. The overhead of constructing the object multiple
times now can outweigh the desired practice of declaring it within
each block.

Constructing an object is often less or at least not more expensive than
assigning to it. I would expect an iterator to take the same time for
assigning to it as for constructing it.
Personally, I prefer to declare i within each loop construct, and then
change that specific piece of code when I port to VC++.

I know it's sometimes necessary to do some changes to conforming code to
make it compile with a specific compiler, but that's not one of those
places. I wouldn't like to do such a change in multiple places if I can
istead just add a single line to make them all work at once without
changing them.
If I forget to change it, the compiler tells me.

Provided that you do not rely on the value of i between or at the
start of any block, but instead assign it a value in the initializer
portion of each for loop, I fail to see where any harm can come from
declaring it once and using it multiple times. (And in the bad old
days when I needed every byte of memory I could get my grubby little
hands on, it was practically a *requirement* that I do it that way!)

You could say the same about the "bad old days" when you needed to count
clock cycles.
 
R

Ron Natalie

Jeff Schwab said:
Of course, you'll have to include the macro in each source file using a
"for" loop. You'll need to be careful not to include before any of the
MS headers, too, to avoid breaking them.
We have a file that is included in each source module anyhow. There
are always implementation dependencies to resolve. Actually, no Microsoft
header seems affected by the change. Even the V7 compiler can compile
all the MS headers (even the earlier ones) with the option turned on that
causes the compiler to use the proper for loop scoping. The problem
is the V6 compiler, doesn't break this out separately. If you disable
ALL extensions (which will get the right for loop scoping), then something
else that the headers relies on gets shut off.
 

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,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top