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

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

haben erklärt, ich ::g oder X::g?Umfang der verschachtelten Funktionsdeklaration in C++

Klirren 3.5 kompiliert und auf diesen Link, wenn ich eine Definition von X::g hinzufügen:

namespace X { 
    void f(); 
} 

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

void X::g() { } 

gcc 4.9.1 lehnt die Definition mit der Meldung:

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

aber wenn ich definieren g in der globale Namespace stattdessen scheint gcc seine Meinung ändern und beschweren sich über das Gegenteil:

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

Da es auch illegal ist, void ::g() innerhalb von f zu deklarieren, scheint es, dass es nicht möglich ist, eine Funktion-Bereich vorwärts Deklaration der globalen Funktion in einer Namespace-Funktion zu haben. Fehle ich etwas? Was genau sind die Scoping-Regeln hier?

g ++ (GCC) 4.9.1; Apple LLVM Version 6.0 (clang-600.0.54) (basierend auf LLVM 3.5svn)

Antwort

6

Funktionsdeklarationen bei Block Scope haben Verknüpfung. [Basic.link]/6:

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

Aber solche Block Umfang Erklärungen mit Verknüpfung einführen keine Namen in umschließenden Namensräume. [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.

Sie deshalb weder haben ::g noch X::g erklärt. Definieren über

void X::g() {} 

ist schlecht gebildet.

Verwandte Themen