Can a 'for' loop inside of a 'for' loop use the same counter variable name?
Solution 1
You may use the same name (identifier). It will be a different object. They will not affect each other. Inside the inner loop, there is no way to refer to the object used in the outer loop (unless you make special provisions for that, as by providing a pointer to it).
This is generally bad style, is prone to confusion, and should be avoided.
The objects are different only if the inner one is defined separately, as with the int i
you have shown. If the same name is used without defining a new object, the loops will use the same object and will interfere with each other.
Solution 2
First, this is absolutely legal: the code will compile and run, repeating the body of the nested loop 10×10=100 times. Loop counter i
inside the nested loop will hide the counter of the outer loop, so the two counters would be incremented independently of each other.
Since the outer i
is hidden, the code inside the nested loop's body would have access only to the value of i
of the nested loop, not i
from the outer loop. In situations when the nested loop does not need access to the outer i
such code could be perfectly justifiable. However, this is likely to create more confusion in its readers, so it's a good idea to avoid writing such code to avoid "maintenance liabilities."
Note: Even though the counter variables of both loops have the same identifier i
, they remain two independent variables, i.e. you are not using the same variable in both loops. Using the same variable in both loops is also possible, but the code would be hard to read. Here is an example:
for (int i = 1 ; i < 100 ; i++) {
for ( ; i % 10 != 0 ; i++) {
printf("%02d ", i);
}
printf("%d\n", i);
}
Now both loops use the same variable. However, it takes a while to figure out what this code does without compiling it (demo);
Solution 3
You can. But you should be aware of the scope of the i
s. if we call the outer i
with i_1
and the inner i
with i_2
, the scope of the i
s is as follows:
for(int i = 0; i < 10; i++)
{
// i means i_1
for(int i = 0; i < 10; i++)
{
// i means i_2
}
// i means i_1
}
You should notice that they do not affect each other, and just their scope of definition is different.
Solution 4
That is completely possible but keep in mind, you wont be able to address the first declared i
for(int i = 0; i < 10; i++)//I MEAN THE ONE HERE
{
for(int i = 0; i < 10; i++)
{
}
}
in the second loop within the second child loop
for(int i = 0; i < 10; i++)
{
for(int i = 0; i < 10; i++)//the new i
{
// i cant see the i thats before this new i here
}
}
if you need to adjust or get the value of the first i, use j in the second loop
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
}
}
and if your creative enough you can do both of them in one loop
for(int i ,j= 0; i < 10; (j>9) ? (i++,j=0) : 0 ,j++)
{
printf("%d %d\n",i,j);
}
Solution 5
Yes you can use the same counter variable name for an inner for
loop as for the outer for
loop.
From for loop:
for ( init_clause ; cond_expression ; iteration_expression ) loop_statement
The expression statement used as loop_statement establishes its own block scope, distinct from the scope of init_clause.for (int i = 0; ; ) { long i = 1; // valid C, invalid C++ // ... }
The scope of loop_statement is nested within the scope of init_clause.
From C Standards#6.8.5p5 Iteration statements [emphasis mine]
An iteration statement is a block whose scope is a strict subset of the scope of its enclosing block. The loop body is also a block whose scope is a strict subset of the scope of the iteration statement.
From C Standards#6.2.1p4 Scopes of identifiers [emphasis mine]
....Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.
Related videos on Youtube
Uclydde
Studying computer science at the University of Central Florida.
Updated on November 22, 2021Comments
-
Uclydde over 2 years
Can I use the same counter variable for a
for
loop inside of afor
loop?Or will the variables affect each other? Should the following code use a different variable for the second loop, such as
j
, or isi
fine?for(int i = 0; i < 10; i++) { for(int i = 0; i < 10; i++) { } }
-
Jonathan Leffler almost 6 yearsIt is confusing — it wouldn't get past me in a code review. But it is legitimate. There are two different variables both called
i
, with different scopes. Use-Wshadow
with GCC to get such problems reported automatically. -
leftaroundabout almost 6 yearsI'm surprised that
-Wshadow
is not included in-Wall
. -
Jörg W Mittag almost 6 yearsYour question is unclear. In your title and in your question, you ask about using "the same counter variable", but in your code example you use different counter variables. What, precisely is it you are asking about?
-
Cubic almost 6 years@leftaroundabout
-Wshadow
warns about shadowing of global variables as well, which could easily get annoying in larger projects. -
hyde almost 6 years@leftaroundabout even more surprisingly, even
-Wextra
does not include-Wshadow
. I guess it is common enough in some projects, or some gcc developer loves shadowing as a coding style, to warrant being left out like this. -
Konrad Rudolph almost 6 years@leftaroundabout Echoing what Cubic said,
-Wshadow
has a horrendous false positive rate, rendering it completely useless. Scope exists for a reason, and shadowing is a priori not problematic. Now-Wshadow-local
(note: not-Wshadow=local
) is very different. But unfortunately GCC has so far refused to include it in trunk (though there appear to be forks of GCC which do include it). -
David Z almost 6 years@JörgWMittag I think JBraha was taking it for granted that there is a one-to-one mapping between names and variables, i.e. that both times
i
was used in the code sample, it refers to the same variable. That seems like a reasonable thing for less-experienced C programmers to assume, even though it turns out not to be correct. I made an edit that should clarify the question, hopefully without changing the meaning - but if I have changed the meaning, someone please fix it. -
Quentin 2 almost 6 yearsIt actually says "use the same name". There are two variables with the same name.
-
David Hammen almost 6 years@KonradRudolph - Just to reiterate, there are some organizations that think that shadowing is a good thing in the right contexts. For example, a C++ constructor or setter that takes arguments with the exact same names as the data members to be constructed or set. I've been told by some that I should use the same names in this context, served with a dish of "did you even read our coding standards" served on the side, while others have said that I absolutely shouldn't do that, served with a dish of "did you even read our coding standards" on the side.
-
-
Easton Bornemeier almost 6 yearsSince the question is phrased as "using the same counter variable" I would also like to point out that the shadowing only takes place when the redefinition occurs. Omitting the
int
on the inner for loop, i.e. actually using the same counter variable, will cause the outer loop to only run once, as the inner loop will leavei == 10
. This is trivial, but thought it provides clarification given how the question was stated -
Sergey Kalinichenko almost 6 years@EastonBornemeier You are right, I figured I should address the issue of "the same variable" in the body of the answer. Thank you!
-
Sergey Kalinichenko almost 6 years@EricPostpischil "Variable shadowing" is an official term, complete with its own page on wikipedia. I've updated the answer to be consistent with the wording of the standard, though. Thank you!
-
Eric Postpischil almost 6 years@dasblinkenlight: Actually, I had a brain spasm about the direction, and the inner name does shadow the outer name. My previous comment was wrong in that regard. My apologies. (However, that is in an English sense, not in an official sense—Wikipedia is not an official publication for C or programming in general, and I am not aware of any office or authoritative body that defines the term.) The C standard uses “hide,” so that is preferable.
-
TripeHound almost 6 yearsNice, especially with the "same variable" example. However, I think "the code will compile and run as expected" would be better as "the code will compile and run as someone who has read it carefully and understands all the ramifications expected" ... as you say, code like this "is likely to create more confusion in its readers" and the problem is a confused reader might expect something other than what it does.
-
KYL3R almost 6 yearsusing for(i) and for(j) nested, and inside i++, will increase the outer-loop variable. However what you say is correct if you use the same identifier in both loops, because they are differently scoped variables.
-
Bloodgain almost 6 yearsIf I caught shadowed i variables in nested loops during a code review, I'd see it as a coaching opportunity. If I caught someone obfuscating the inner loop like your last example (that is NOT one loop), I might throw them out a window.
-
Eric Postpischil almost 6 years@BloodGain: “Object” is a technical term used in the C standard. I used it deliberately here.
-
Bloodgain almost 6 years@EricPostpischil: Ah, I see, yes. I was not aware of that definition in the standard, and was afraid it would be misleading to new programmers (as this is very clearly a beginner question), since C does not have "objects" in the sense that we generally use the term. I see it in the C11 standard, and now I'm curious if it was defined that way before C11.
-
Bloodgain almost 6 yearsIt was. It's 3.14 in the C99 standard, instead of 3.15. So no excuse on my part. That'll teach me to question you <:-|
-
Dodo almost 6 yearsit is one loop, it has only one for loop, if it was 2 it would have two for keywords or two while keywords or a for and while keywords
-
Bloodgain almost 6 yearsThat's why I said you obfuscated the loop. You're still looping, you've just hidden it with less obvious syntax. And it's worse in every way for it.
-
Isaac Rabinovitch over 5 yearsMore generally: there's nothing to prevent you from re-using a variable name in any nested scope. Except, of course, the fear of God's Punishment for writing confusing code.
-
Jeremy Caney over 2 yearsThere are twelve existing answers to this question, including an accepted answer with 142 upvotes. Are you sure your answer hasn't already been provided? If not, why might someone prefer your approach over the existing approaches proposed? Are you taking advantage of new capabilities? Are there scenarios where your approach is better suited?
-
kevinarpe about 2 yearsIs there a compiler (GCC, etc) argument to explicitly forbid this type of code? I recently wrote code exaclty like this... It was like a joke of electricity finding this "bug" -- How was this allowed by my compiler (GCC)???
-
Eric Postpischil about 2 years@kevinarpe: It is allowed by your compiler because it is a desired and intentional specified part of the C language. It is generally not a problem because people rarely stick one loop inside another that needs an identifier of the outside loop without paying attention to the newly inserted loop. On the other hand, a “self contained” loop may be inserted inside another loop, sometimes by way of a macro, and it does not need or care about identifiers of the outer loop. As a matter of actual practice, this is sometimes a convenience and is rarely a problem, so warning about it is off by default.
-
Eric Postpischil about 2 years@kevinarpe: Nonetheless, GCC and Clang have a switch to warn about it,
-Wshadow
, or the more specific-Wshadow=local
that warns only if a local identifier shadows another local identifier.