Reputation: 21251
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
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