From [basic.scope.declarative], the definition of a "declarative region" is:
Every name is introduced in some portion of program text called a declarative region, which is the largest part
of the program in which that name is valid, that is, in which that name may be used as an unqualified name
to refer to the same entity.
The restriction is, emphasis mine:
Given a set of declarations in a single declarative region, each of which specifies the same unqualified name
— they shall all refer to the same entity, or all refer to functions and function templates
Going back to your example. If we annotate the two declarative regions, we have:
namespace A{} + region #1
|
int main() | +
{ | |
int A; | | region #2
| |
} + +
The declarative regions for namespace A
(#1) and int A
(#2) are different (the second is a strict subset of the first, but that doesn't matter). Since they are different, the restriction on having a single name doesn't apply. There is one single A
in #2 and one single A
in #1.
If we, however, moved int A
to be in the same declarative region:
namespace A {} + the only declarative region. even though the
int A; | potential scope of "int A" does not include
| "namespace A", the declarative region does.
int main() { | The intent of this is expressed in the example
| in [basic.scope.declarative]/2:
| int main() {
| int i = j, j;
| j = 42;
| }
|
| "The declarative region of the [j] includes all
| the text between { and }, but its potential scope
} + excludes the declaration of i."
That would violate [basic.scope.declarative]/4, and both gcc and clang correctly reject the code with:
error: redefinition of 'A
' as different kind of symbol
Note that as Vaughn Cato points out, there is an active defect report about the wording for declarative region.