16

This snippet compiles in clang,

namespace A {
    void f() {
        void g();
        g();
    }
}

void A::g() { }

but GCC only accepts the code if g is defined inside the namespace A as follows:

namespace A {
    void f() {
        void g();
        g();
    }
    void g() {}
}

But I believe there's nothing in [basic.link]/7 disallowing the first snippet above.

abcd
  • 10,215
  • 15
  • 51
  • 85
Leon
  • 868
  • 4
  • 12

2 Answers2

18

[basic.link]/p7, emphasis mine:

When a block scope declaration of an entity with linkage is not found to refer to some other declaration, then that entity is a member of the innermost enclosing namespace. However such a declaration does not introduce the member name in its namespace scope.

[namespace.memdef]/p2, emphasis mine:

Members of a named namespace can also be defined outside that namespace by explicit qualification (3.4.3.2) of the name being defined, provided that the entity being defined was already declared in the namespace and the definition appears after the point of declaration in a namespace that encloses the declaration’s namespace.

GCC is correct. Your first snippet is ill-formed.

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • You're right. I've missed to notice [namespace.memdef]/2. (+1) – Leon Apr 28 '15 at 20:27
  • By the way, is there anything actually speaking against locally defined functions? Apparently, local classes can define their member functions locally. – Columbo Apr 28 '15 at 20:35
  • @Columbo [dcl.fct.def.general]/p2 – T.C. Apr 28 '15 at 20:43
  • @T.C. I wasn't talking about the current standard, but about the possibility of introducing it. – Columbo Apr 28 '15 at 20:44
  • @Columbo Oh, you mean "is there any reason why we don't have such a feature"? – T.C. Apr 28 '15 at 20:45
  • @T.C. Yes, or "Is there any reason why we cannot introduce it?" E.g. linkage, or what not. – Columbo Apr 28 '15 at 20:45
  • @Columbo At this point, with lambdas in the language, I doubt that we'll ever have them, whether or not technically feasible. – T.C. Apr 28 '15 at 20:47
  • @T.C. I know. That doesn't answer my question though. :) I just wanna know whether there is a fundamental technical reason that doesn't allow us to do it. (Probably not, so nvm.) – Columbo Apr 28 '15 at 20:48
  • @Columbo I doubt that it's technically infeasible, but you'd presumably have to give them external linkage to match local function declarations, and that can make for some very confusing code. – T.C. Apr 28 '15 at 20:56
4

It seems pretty clear to me from [basic.link]/7

...However such a declaration does not introduce the member name in its namespace scope.

that clang is wrong. Similarly you wouldn't expect this to compile:

namespace A
{
}

void A::foo()
{
}
Mark B
  • 95,107
  • 10
  • 109
  • 188