Why don't these names with external linkage denote the same entity?

Consider the following code snippet:

#include <iostream>

int a;
void address_of_a(void) {
    std::cout << &a << std::endl;
}

namespace N {
    int a;
    void address_of_a(void) {
        std::cout << &a << std::endl;
    }   
};

int main(void) {
    address_of_a();
    N::address_of_a();
    return 0;
}

The global namespace and named namespace N are given external linkage because 3.5 [basic.link] paragraph 4 from N4567 says that

An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage...

Furthermore, ::a and N::a are also given external linkage because they are not applicable to 3.5 [basic.link] paragraph 3,

A name having namespace scope (3.3.6) has internal linkage if it is the name of

  • a variable, function or function template that is explicitly declared static; or,
  • a variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage; or
  • a data member of an anonymous union.

but to 3.5 [basic.link] paragraph 4,

... A name having namespace scope that has not been given internal linkage above has the same linkage as the enclosing namespace if it is the name of

  • a variable; or
  • ...

which means to say that they inherit the same linkage(=external linkage) as the global namespace and N. In conclusion, they shall denote the same entity because 3.5 [basic.link] paragraph 9 says that

Two names that are the same (Clause 3) and that are declared in different scopes shall denote the same variable, function, type, enumerator, template or namespace if

  • both names have external linkage or both names have internal linkage and are declared in the same translation unit; and
  • ...

However, they seem to denote different entities because their addresses didn't coincide. Why is that?

Upvotes: 1

Views: 116

Answers (1)

cpplearner
cpplearner

Reputation: 15898

See the second bullet.

Two names that are the same (Clause 3) and that are declared in different scopes shall denote the same variable, function, type, enumerator, 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

  • both names refer to members of the same namespace or to members, not by inheritance, of the same class; and

  • when both names denote functions, the parameter-type-lists of the functions (8.3.5) are identical; and

  • when both names denote function templates, the signatures (14.5.6.1) are the same.

::a and N::a do not refer to members of the same namespace, so they do not denote the same variable.

Upvotes: 5

Related Questions