Противоречивые результаты между GCC и clang, связанные с [basic.link]/7 в стандарте С++

Этот фрагмент компилируется в clang,

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

void A::g() { }

но GCC принимает только код, если g определяется внутри пространства имен A следующим образом:

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

Но я не считаю, что в [basic.link]/7 ничего не говорится о первом фрагменте выше.

Ответы

Ответ 1

[basic.link]/p7, акцент мой:

Если объявление области видимости объекта с привязкой не найдено чтобы ссылаться на какое-то другое выражение, то эта организация является членом самое внутреннее пространство имен. Однако такая декларация не введите имя члена в область пространства имен.

[namespace.memdef]/p2, акцент мой:

Члены именованного пространства имен также могут быть определены вне этого пространства имен посредством явной квалификации (3.4.3.2) имени при условии, что уже определенная сущность в пространстве имен и определение появляется после точки объявление в пространстве имен, которое охватывает пространство имен объявлений.

GCC правильный. Ваш первый фрагмент плохо сформирован.

Ответ 2

Мне кажется довольно понятным от [basic.link]/7

... Однако такое объявление не вводит имя участника в его область пространства имен.

что clang ошибочно. Точно так же вы не ожидали, что это скомпилируется:

namespace A
{
}

void A::foo()
{
}