GCC和clang之间的矛盾结果与C++标准中的[basic.link]/7有关

Leo*_*eon 16 c++ linkage language-lawyer c++11 c++14

这个片段编译成clang,

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

void A::g() { }
Run Code Online (Sandbox Code Playgroud)

但GCC只接受代码,如果g在命名空间内定义A如下:

namespace A {
    void f() {
        void g();
        g();
    }
    void g() {}
}
Run Code Online (Sandbox Code Playgroud)

但我相信[basic.link]/7中没有任何内容禁止上面的第一个片段.

T.C*_*.C. 18

[basic.link]/p7,强调我的:

当找不到具有链接的实体的块范围声明来引用其他声明时,该实体是最内层封闭命名空间的成员.但是,此类声明不会在其命名空间范围中引入成员名称.

[namespace.memdef]/p2,强调我的:

通过定义名称的显式限定(3.4.3.2),也可以在该命名空间外定义命名空间的成员,前提是已定义的实体已在命名空间中声明,并且定义出现在命名空间中的声明点之后包含声明的命名空间.

GCC是正确的.你的第一个片段是不正确的.