The following program compiles without errors with MSVS, clang and GCC:
class A;
namespace Y {
using ::A;
class A {};
}
int main() {}
Now let's define a member function. Now it still compiles with MSVS and clang, but not with GCC:
class A;
namespace Y {
using ::A;
class A { void f() {} };
}
int main() {}
GCC gives the following error message:
Why is that? Is this a bug in GCC?
If the second version of the program violates a rule of the c++ standard, what rule does it violate and why doesn't MSVS and clang give a diagnostic message for that violation?
Is this a case of an ambiguity of the c++ standard?
From the error message it looks like GCC incorrectly thinks we have a violation of the following rule:
We do not have a violation of this rule since the member function definition is inside the class definition. My theory is that GCC confuses the declaration class A; in the global namespace with the class definition class A { ... } in the namespace Y. I think we have a bug in GCC.
With GCC they declare the same entity. This can be seen by observing that in the first version of the program it possible to use ::A as a complete type in main when compiling with GCC. Same for MSVS. With Clang however they declare different entities. This difference may be because of an ambiguity in the c++ standard. Regardless of such an ambiguity we are clearly not violating http://eel.is/c++draft/class.mfct#2 . That rule is very clear.
Related question: Class declaration in same scope as using declaration compiles in GCC but not MSVS
Both of these programs are ill-formed according to the c++ standard. This is because of the same reason as in the related question:
Class declaration in same scope as using declaration compiles in GCC but not MSVS
All compilers should give a compile error in both cases: So this indicates a bug in MSVS, clang and GCC.
The bug in clang has been confirmed and fixed: https://llvm.org/bugs/show_bug.cgi?id=24030
The reason that GCC gives a strange error message for the second program is that it gets confused when it failed to detect the error that is present in both the first and the second program.