Consider this snippet of a C program:
for(int i = 0; i < 5; i++)
{
int i = 10; // <- Note the local variable
printf("%d", i);
}
It compiles without any error and, when executed, it gives the following output:
1010101010
But if I write a similar loop in C++:
for(int i = 0; i < 5; i++)
{
int i = 10;
std::cout << i;
}
The compilation fails with this error:
prog.cc:7:13: error: redeclaration of 'int i'
int i = 10;
^
prog.cc:5:13: note: 'int i' previously declared here
for(int i = 0; i < 5; i++)
^
Why is this happening?
This is because C and C++ languages have different rules about re-declaring variables in a scope nested in a
for
loop:C++
putsi
in the scope of loop's body, so the secondint i = 10
is a redeclaration, which is prohibitedC
allows redeclaration in a scope within afor
loop; innermost variable "wins"Here is a demo of a running C program, and a C++ program failing to compile.
Opening a nested scope inside the body fixes the compile error (demo):
Now
i
in thefor
header andint i = 10
are in different scopes, so the program is allowed to run.Unlike C, C++ has the rule,
C++11-§6.5.3/1:
This means that the scope of the
for-init-statement
and thestatement
are the same* and the code below will cause errorIn C,
C11-§6.8.5/5:
Therefore,
statement
has it's own scope and the above code is valid and equivalent toSuggested reading: n3337: 6.5.1 The while statement/p(2). Same reference can be found in c++17 draft (n4659) in section § 9.5.1 and §9.5.3 .
It's not redeclaration.
See this carefully...
Output of the above code:-
Clearly, there are two different
i
'sThe newer
i
has a more local scope.Is it a bug?
No
What is the purpose?
If it wasn't allowed, it might be very hard to maintain large projects, as you would constantly run into naming collisions.
Generally though, it is considered very poor practice to give the same name to different variables in different scopes, you should avoid doing that whenever possible.
Why is there no warning message?
Use
gcc file_name.c -Wshadow
to compile.EDIT: You can also locally lock the originally declared variables by redeclaring them in for loops.