namespace X {
void f();
}
void X::f() {
void g();
g();
}
我是否已声明::g
或X::g
?
X::g
的定义:,clang 3.5将编译并链接此内容
namespace X {
void f();
}
void X::f() {
void g();
g();
}
void X::g() { }
gcc 4.9.1用消息拒绝定义:
错误:'void X :: g()'应该在'X'
中声明
但是如果我在全局命名空间中定义g
,gcc似乎改变了它的想法并抱怨相反的事情:
Undefined symbols for architecture x86_64: "X::g()", referenced from: X::f() in ccABCDEF.o
因为在void ::g()
内声明f
也是非法的,似乎不可能在命名空间函数中具有全局函数的函数范围前向声明。我错过了什么吗?这里的范围规则究竟是什么?
g ++(GCC)4.9.1; Apple LLVM 6.0版(clang-600.0.54)(基于LLVM 3.5svn)
答案 0 :(得分:6)
块范围内的函数声明具有链接。 [basic.link] / 6:
在块作用域中声明的函数的名称和[..]具有链接。
但是这种带有链接的块作用域声明不会将任何名称引入封闭的名称空间。 [basic.link] / 7:
当找不到具有链接的实体的块范围声明时 引用一些其他声明,然后该实体是其成员 最里面的封闭命名空间。 但是这样的宣言没有 在名称空间范围内引入成员名称。
因此,您既未宣布::g
也未X::g
。通过
void X::g() {}
是不正确的。