Bikineev
Bikineev

Reputation: 1777

Inline namespaces and ambigous declarations

I'm wondering if this is allowed:

namespace A {
  inline namespace B {
    int a;
  }
  int a;
}

void foo() {
  A::a = 0; // clang 3.4 compiles, but gcc doesn't
}

Standard says, that

Finally, looking up a name in the enclosing namespace via explicit qualification (3.4.3.2) will include members of the inline namespace brought in by the using-directive even if there are declarations of that name in the enclosing namespace.

But I can't get it.

Upvotes: 3

Views: 282

Answers (1)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158529

It looks like this was a pre clang 3.5 bug and there are two defect reports on this 812 and 861. The resolution is in 861 and adds the following to 3.4.3.2 [namespace.qual] (emphasis mine going forward):

For a namespace X and name m, the namespace-qualified lookup set S(X,m) is defined as follows: Let S'(X,m) be the set of all declarations of m in X and the inline namespace set of X (7.3.1 [namespace.def]). If S'(X,m) is not empty, S(X,m) is S'(X,m); otherwise, S(X,m) is the union of S(Ni,m) for all non-inline namespaces Ni nominated by using-directives in X and its inline namespace set.

and the also relevant additions:

if S(X,m) is the empty set, the program is ill-formed. Otherwise, if S(X,m) has exactly one member, or if the context of the reference is a using-declaration (7.3.3 [namespace.udecl]), S(X,m) is the required set of declarations of m. Otherwise if the use of m is not one that allows a unique declaration to be chosen from S(X,m), the program is ill-formed.

It looks like the change was added pre C++11, this text is present in N3337.

Upvotes: 5

Related Questions