The variable redeclared in the outermost block of a substatement
No.
You're missing the block scope introduced by the else
substatement:
[stmt.selected.general/2]
: The substatement in a selection-statement (each substatement, in theelse
form of theif
statement) implicitly defines a block scope ([basic.scope]). If the substatement in a selection-statement is a single statement and not a compound-statement, it is as if it was rewritten to be a compound-statement containing the original substatement. [..]
i.e. your code is really:
#include <iostream>
int main()
{
int b = 2;
if (int a = 0) {
}
else {
if (b == 2) {
int a;
}
}
}
Thus, the block you're looking at (the one introduced by the nested if
) is not the "outermost" block in question. So, though a
is in scope within that block, it can be shadowed.
This does mean you can't declare an a
inside a "naked" else
, i.e. the following is ill-formed:
#include <iostream>
int main()
{
int b = 2;
if (int a = 0) {
}
else {
int a;
}
}
/*
prog.cpp: In function ‘int main()’:
prog.cpp:9:9: error: redeclaration of ‘int a’
int a;
^
prog.cpp:6:11: note: ‘int a’ previously declared here
if (int a = 0) {
*/
The statement in stmt.stmt#stmt.pre-5 explicitly says:
[Note 2: A name introduced in a selection-statement or iteration-statement outside of any substatement is in scope from its point of declaration until the end of the statement's substatements. Such a name cannot be redeclared in the outermost block of any of the substatements ([basic.scope.block]). — end note]
The key term here is outermost block which is defined in stmt.block#1:
A compound statement (also known as a block) groups a sequence of statements into a single statement.
compound-statement:
{ statement-seq opt }
...
A compound statement defines a block scope.
So stmt.stmt#stmt.pre-5 is essentially saying:
if (int a = 0)
{ // outermost block
int a; // so ill-formed
}
but
if (int a = 0)
{ // outermost block
{ // inner block
int a; // so well-formed
}
}
The same rules apply in your example with the block introduced by the nested if
statement.