2014-10-28 31 views
13
namespace X { 
    void f(); 
} 

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

我是否聲明瞭::gX::gC++中嵌套函數聲明的範圍

鐺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()’ should have been declared inside ‘X’

,但如果我定義g在全球命名空間,海灣合作委員會似乎改變了主意,並抱怨相反:

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

因爲在f之內聲明void ::g()也是非法的,所以似乎不可能在名稱空間函數中具有全局函數的函數範圍前向聲明。我錯過了什麼嗎?這裏的範圍規則究竟是什麼?

g ++(GCC)4.9.1; Apple LLVM 6.0版(clang-600.0.54)(基於LLVM 3.5svn)

回答

6

塊範圍的函數聲明具有鏈接。 [basic.link]/6:

The name of a function declared in block scope and [..] have linkage.

但是,這種帶連接的塊範圍聲明不會將任何名稱引入到包含名稱空間中。 [basic.link]/7:

When a block scope declaration of an entity with linkage is not found to refer to some other declaration, then that entity is a member of the innermost enclosing namespace. However such a declaration does not introduce the member name in its namespace scope.

您已因此既不宣佈::g也不X::g。通過定義它

void X::g() {} 

是不合格的。