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:
- prog.cc:5:22: error: definition of 'void A::f()' is not in namespace enclosing 'A' [-fpermissive]
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:
- http://eel.is/c++draft/class.mfct#2 "A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition."
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