Fedor
Fedor

Reputation: 21251

Ambiguity accessing identifier in global and nested anonymous namespaces

The following code:

namespace { constexpr int x = 1; }
namespace X { namespace { constexpr int x = 2; } }
using namespace X;

int main() {
  static_assert( ::x == 1 );
}

successfully compiles in MSVC, which prefers the first anonymous namespace in finding of ::x over X::(anonymous namespace).

However both GCC and Clang reject the code due to ambiguity of selection. Demo: https://gcc.godbolt.org/z/zPEGzGar3

Which compiler is right here?

Upvotes: 3

Views: 113

Answers (1)

rustyhu
rustyhu

Reputation: 2147

There is a similar example in this reference of unnamed namespaces:

namespace {
    int i; // defines ::(unique)::i
}
void f() {
    i++;   // increments ::(unique)::i
}
 
namespace A {
    namespace {
        int i;        // A::(unique)::i
        int j;        // A::(unique)::j
    }
    void g() { i++; } // A::(unique)::i++
}
 
using namespace A; // introduces all names from A into global namespace
void h() {
    i++;    // error: ::(unique)::i and ::A::(unique)::i are both in scope
    A::i++; // ok, increments ::A::(unique)::i
    j++;    // ok, increments ::A::(unique)::j
}

According to this, rejecting the code due to ambiguity of selection by GCC and Clang should be correct.

Namespaces provide a method for preventing name conflicts in large projects.

Symbols declared inside a namespace block are placed in a named scope that prevents them from being mistaken for identically-named symbols in other scopes.

As this explanation states, namespace is introduced to avoid or solve the name conflicts. IMHO these code examples are obviously trying to make name conflicts.

Upvotes: 2

Related Questions