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

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

ho io dichiarata ::g, o X::g?Ambito di dichiarazione di funzione annidata in C++

clang 3.5 sarà compilare e linkare questo se aggiungo una definizione di X::g:

namespace X { 
    void f(); 
} 

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

void X::g() { } 

gcc 4.9.1 rifiuta la definizione con il messaggio:

error: ‘void X::g()’ should have been declared inside ‘X’

ma se io definisco g in lo spazio dei nomi globale invece, gcc sembra cambiare idea e lamentarsi del contrario:

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

Poiché è anche illegale dichiarare void ::g() all'interno di f, sembra che non sia possibile avere una dichiarazione forward della funzione scope della funzione globale in una funzione namespace. Mi sto perdendo qualcosa? Quali sono esattamente le regole di scoping qui?

g ++ (GCC) 4.9.1; Apple LLVM versione 6.0 (clang-600.0.54) (basato su LLVM 3.5svn)

risposta

6

Le dichiarazioni di funzione a livello di blocco hanno un collegamento. [Basic.link]/6:

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

Ma tali dichiarazioni blocco scope con linkage non introducono alcun nome in namespace racchiudono. [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.

Si sono quindi né dichiarata né ::gX::g. Definirlo tramite

void X::g() {} 

è mal formato.