It seems like using the same variable 'i' to iterate through the two for-loops would overlap and cause errors.
Indeed, it would. Well, not "errors", so much as unexpected behavior. The code you have is syntactically fine; no C or C++ compiler that I know of would raise any warnings, much less errors. However, if you run it, you'll see that it merely loops through 20 times (i
= 0 to 19).
Why? Because the i
variable is a global variable, shared across both functionA
and functionB
. functionA
initializes i
to 0, then immediately (first iteration of the loop) calls functionB
. functionB
resets i
back to 0 and then loops through 20 times before returning. Upon return to functionA
, i
has the value 19. That is not less than 10, so the check in the for
loop's ending condition inside of functionA
fails and the loop exits.
The behavior is correct and predicable, but unexpected, assuming that you were intending the loop in functionA
to run through 10 times.
This is why shared state should be avoided whenever possible: it makes the behavior of a program more difficult to reason about.
Is there an easier way to do this, like maybe making a variable private to one for-loop?
Yes, that is precisely what you should do. In fact, always prefer to reduce the scope of a variable whenever possible. What you have now is a global variable. Making a local variable (one that is local to each function) would be preferable, e.g.:
void functionA (){
int i;
for (i=0; i<10; i++){
functionB();
}
}
void functionB (){
int i;
for (i=0; i<20; i++){
doSomething();
}
}
But even better is to actually scope the index variable to the for
loop itself. That can be done by declaring the variable within the loop statements:
void functionA (){
for (int i=0; i<10; i++){
functionB();
}
}
void functionB (){
for (int i=0; i<20; i++){
doSomething();
}
}
Personally, I like to write the increment statement as ++i
, since that's a better reflection of what is actually happening. As a bonus, it may, with certain types of objects, in certain languages, be more efficient. But in C and/or with an int
, both forms result in identical object code. I just prefer the pre-increment.
for (int i = 0; i < length; i++)
. It's local to the loop block, and it goes out of scope when the loop ends; you can reuse the name all you like.