Подтвердить что ты не робот

Область описания вложенной функции в С++

namespace X {
    void f();
}

void X::f() {
    void g();
    g();
}

Объявил ли я ::g или X::g?

clang 3.5 скомпилирует и свяжет это, если я добавлю определение X::g:

namespace X {
    void f();
}

void X::f() {
    void g();
    g();
}

void X::g() { }

gcc 4.9.1 отклоняет определение сообщением:

error: "void X:: g() должен быть объявлен внутри" X

но если я определяю g в глобальном пространстве имен, gcc, похоже, изменяет его и жалуется на обратное:

Undefined symbols for architecture x86_64:
  "X::g()", referenced from:
      X::f()     in ccABCDEF.o

Так как также запрещено объявлять void ::g() внутри f, похоже, что в функции пространства имен невозможно объявить глобальную функцию функции-scope. Я что-то упускаю? Какие именно правила охвата здесь?

g++ (GCC) 4.9.1; Apple LLVM версии 6.0 (clang-600.0.54) (на основе LLVM 3.5svn)

4b9b3361

Ответ 1

Объявление функций в области блока имеет привязку. [Basic.link]/6:

Имя функции, объявленной в области блока, и [..] имеют связь.

Но такие объявления области блока с привязкой не вводят никаких имен в пространство имен. [Basic.link]/7:

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

Поэтому вы не объявили ::g и X::g. Определение его через

void X::g() {}

плохо сформировался.