Область описания вложенной функции в С++
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)
Ответы
Ответ 1
Объявление функций в области блока имеет привязку. [Basic.link]/6:
Имя функции, объявленной в области блока, и [..] имеют связь.
Но такие объявления области блока с привязкой не вводят никаких имен в пространство имен. [Basic.link]/7:
Если объявление области видимости объекта с привязкой не найдено чтобы ссылаться на какое-то другое выражение, то эта организация является членом самое внутреннее пространство имен. Однако такая декларация не введите имя члена в область пространства имен.
Поэтому вы не объявили ::g
и X::g
. Определение его через
void X::g() {}
плохо сформировался.