I compile this program by g++ and clang++. There has a difference:
g++ prints 1, but clang++ prints 2.
It seems that
g++: the extern varible is defined in the shorte
Clang gives a right result. Even though per the rule of the current standard, the program shouldn't be ill-formed. Note the emphasized wording:
If, within a translation unit, the same entity is declared with both internal and external linkage, the program is ill-formed.
The entity declared at #3
and the entity declared at #1
are not the same entity, because of the below rule:
Two names that are the same and that are declared in different scopes shall denote the same variable, function, type, template or namespace if
- both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and
- [...]
They're not, one has internal linkage
and the other has external linkage
, so they do not denote the same entity, hence the code does not violate the [basic.link#6]. Moreover, the example follows [basic.link#6] remains a wrong interpretation about variable i
.
P1787 has clarified this example. It says:
static void f();
extern "C" void h();
static int i = 0; // #1
void gq() {
extern void f(); // internal linkage
extern void g(); // ::g, external linkage
extern void h(); // C language linkage
int i; // #2: i has no linkage
{
extern void f(); // internal linkage
extern int i; // #3: exinternal linkage
}
}
Without Even though the declaration at line #2 hides the declaration at line #1, the declaration at line #3 would link with thestill redeclarationes at line #1. Because the declaration with and receives internal linkage is hidden, however, #3 is given external linkage, making the program ill-formed.
That means, In your example, the variable i
introduced by declaration extern int i
will link with the variable i
declared by static int i
. So, print 2
is the right behavior.