Anonyme Namespaces



  • namespace {	
    	struct person
    	{
               //...
            };
    }
    

    welchen Sinn haben anonyme Namespaces?

    warum schreiben machen vor ihren API Aufrufen ein :: z. B.:

    ::GetCursorPos(&pt);
    


  • Anonyme Namensräume begrenzen die Verfügbarkeit der enthaltenen Definitionen auf die Übersetzungseinheit, in der sie stehen - d.h. außerhalb deiner CPP kann niemand die sehen.

    ::GetCursorPos(...) ruft die genannte Funktion im globalen Namensraum auf (das ist alles, was nicht in namespace xyz{...} verpackt ist). Das wird vor allem dann nützlich, wenn du eine gleichnamige Methode hast, die du eben nicht aufrufen willst.
    (GUI-Klassen machen das häufig, um einen Wrapper um die WinAPI bereitzustellen)



  • D. h. wenn ich in foo.cpp eine Variable int muh; habe und in bar.cpp extern int muh; dann kann ich in bar.cpp auf die Variable von foo.cpp zugreifen. Wenn ich jetzt aber das ganze in einen anonynmen Namespace packe, dann geht das nicht mehr?



  • Genau, du hast durch anonyme Namensräume wie bei static interne Bindung. Nur kannst du das nicht nur auf Variablen und Funktionen anwenden, sondern auf beliebige Symbole (z.B. Klassen und andere Typen).



  • Wenn du in beiden Quellen ein int muh; stehen hast, bekommst du vor allem eins - einen Linker-Fehler wegen mehrfacher Definition. Um wechselweise auf die Variable zugreifen zu können, muß einer als extern deklariert werden (dann hast du nur eine Variable, die von beiden Übersetzungseinheiten genutzt werden kann).



  • muhkuh27 schrieb:

    D. h. wenn ich in foo.cpp eine Variable int muh; habe und in bar.cpp extern int muh; dann kann ich in bar.cpp auf die Variable von foo.cpp zugreifen. Wenn ich jetzt aber das ganze in einen anonynmen Namespace packe, dann geht das nicht mehr?



  • Ich habe schon gehört, dass es im neuen Standard( wird wahrscheinlich aber nicht der Fall sein ) globale static variablen verboten sind. Sprich du müssten immer anonyme namespaces nutzen. Anonyme namespaces sind quasi das C++ äquivalent zu static im globalen namensraum.

    LG freeG



  • verboten nicht, aber deprecated.

    und nicht "äquivalent zu static im globalen namensraum" sondern "alternative zu static auf namespace ebene".
    also weder äquivalent noch beschränkt auf den globalen namespace.
    (unterschied ist z.b. dass static zu internal linkage führt, dinge in einem anonymous namespace aber external linkage haben.)



  • hustbaer schrieb:

    (unterschied ist z.b. dass static zu internal linkage führt, dinge in einem anonymous namespace aber external linkage haben.)

    Nope.
    Anonyme Namespaces haben internal linkage, und "alles" was sich in einem namespace mit internal linkage befindet, hat ebenfalls internal linkage.

    N3291, §3.5/4 schrieb:

    An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has
    internal linkage
    . All other namespaces have external linkage. A name having namespace scope that has not
    been given internal linkage above has the same linkage as the enclosing namespace if it is the name of
    — a variable; or
    — a function; or
    — a named class (Clause 9), or an unnamed class defined in a typedef declaration in which the class has
    the typedef name for linkage purposes (7.1.3); or
    — a named enumeration (7.2), or an unnamed enumeration defined in a typedef declaration in which the
    enumeration has the typedef name for linkage purposes (7.1.3); or
    — an enumerator belonging to an enumeration with linkage; or
    — a template.

    (Hervorhebungen hinzugefügt)



  • hustbaer schrieb:

    verboten nicht, aber deprecated.

    und nicht "äquivalent zu static im globalen namensraum" sondern "alternative zu static auf namespace ebene".
    also weder äquivalent noch beschränkt auf den globalen namespace.
    (unterschied ist z.b. dass static zu internal linkage führt, dinge in einem anonymous namespace aber external linkage haben.)

    pumuckl schrieb:

    hustbaer schrieb:

    (unterschied ist z.b. dass static zu internal linkage führt, dinge in einem anonymous namespace aber external linkage haben.)

    Nope.
    Anonyme Namespaces haben internal linkage, und "alles" was sich in einem namespace mit internal linkage befindet, hat ebenfalls internal linkage.

    Sage ich doch, damit ist es äquivalent zu static im globalen Namensraum 🙄 .

    Lg freeG



  • fr33g schrieb:

    Sage ich doch, damit ist es äquivalent zu static im globalen Namensraum 🙄 .

    Ist es nicht. Ersetze hier den anonymen Namespace durch static:

    #include <iostream>
    using namespace std;
    
    static int x = 0;
    
    namespace
    {
    	int x = 1;
    
    	void foo()
    	{
    		cout << x << endl;
    	}
    }
    
    int main()
    {
    	cout << ::x << endl;
    	foo();
    }
    


  • Michael E. schrieb:

    fr33g schrieb:

    Sage ich doch, damit ist es äquivalent zu static im globalen Namensraum 🙄 .

    Ist es nicht. Ersetze hier den anonymen Namespace durch static:

    #include <iostream>
    using namespace std;
    
    static int x = 0;
    
    namespace
    {
    	int x = 1;
    
    	void foo()
    	{
    		cout << x << endl;
    	}
    }
    
    int main()
    {
    	cout << ::x << endl;
    	foo();
    }
    

    Verstehe gerade nicht was du mir hiermit sagen willst? Wieso soll ich was neueres durch etwas altes ersetzen? Das was static im globalen Bereich kann, kann ein anonymer Namespace auch, daher nutze ich diesen anstatt das globale static.

    Also da wo ich ein

    static typ variable
    

    habe, kann ich es doch immer durch einen anonymen Namespace ersetzten, was dann den gleichen Zweck erfüllt.

    Lg freeG



  • pumuckl schrieb:

    hustbaer schrieb:

    (unterschied ist z.b. dass static zu internal linkage führt, dinge in einem anonymous namespace aber external linkage haben.)

    Nope.
    Anonyme Namespaces haben internal linkage, und "alles" was sich in einem namespace mit internal linkage befindet, hat ebenfalls internal linkage.

    Ja, du hast Recht.
    Hatte ich falsch in Erinnerung. Peinlich.
    Ist auch irgendwie logisch, wenn man darüber nachdenkt -- woher soll der Compiler wissen was als das selbe Objekt angesehen werden muss, und was nicht? Also wenn z.B. ein unnamed namespace in einem Header-File verwendet wird.

    @fr33g:
    Ja, man kann immer unnamed namespaces nehmen, wo vorher static war.
    Umgekehrt geht es aber nicht immer.



  • hustbaer schrieb:

    @fr33g:
    Ja, man kann immer unnamed namespaces nehmen, wo vorher static war.
    Umgekehrt geht es aber nicht immer.

    Ja da gebe ich dir recht, habe ich auch nie behauptet;-) Ist ja meistens so, dass Neuerungen mehr können als ihre Vorgänger. Es ist ja auch ein Namespace und nicht einfach nur ein Schlüsselwort wie static.

    Lg freeG



  • fr33g schrieb:

    hustbaer schrieb:

    Ja, man kann immer unnamed namespaces nehmen, wo vorher static war.
    Umgekehrt geht es aber nicht immer.

    Ja da gebe ich dir recht, habe ich auch nie behauptet;-)

    Doch, du hast von "äquivalent" gesprochen 🙂

    Wie schon gesagt haben anonyme Namensräume vor allem Vorteile, wenn man mehr als nur Variablen oder Funktionen mit interner Linkage versehen will.



  • Nexus schrieb:

    fr33g schrieb:

    hustbaer schrieb:

    Ja, man kann immer unnamed namespaces nehmen, wo vorher static war.
    Umgekehrt geht es aber nicht immer.

    Ja da gebe ich dir recht, habe ich auch nie behauptet;-)

    Doch, du hast von "äquivalent" gesprochen 🙂

    Wie schon gesagt haben anonyme Namensräume vor allem Vorteile, wenn man mehr als nur Variablen oder Funktionen mit interner Linkage versehen will.

    Ja im Grunde genommen ist es ja auch äquivalent, man kann es wie schon gesagt im globalen Namensraum für Variablen benutzen die als static deklariert sind um das Gleiche zu erreichen. Damit ist es äquivalent, wobei es noch mehr kann, das heißt aber nicht dass es in diesem Fall nicht äquivalent ist 😉

    Lg freeG



  • fr33g schrieb:

    Damit ist es äquivalent, wobei es noch mehr kann

    Nur damit du dir über den Begriff im Klaren bist: Äquivalent heisst gleichwertig und damit normalerweise auch austauschbar.

    Aber keine Sorge, ich verstehe schon, was du sagen willst 😉



  • Nexus schrieb:

    fr33g schrieb:

    Damit ist es äquivalent, wobei es noch mehr kann

    Nur damit du dir über den Begriff im Klaren bist: Äquivalent heisst gleichwertig und damit normalerweise auch austauschbar.

    Aber keine Sorge, ich verstehe schon, was du sagen willst 😉

    Dann bin ich ja beruhigt:-P 🙂

    Ich kenne die Bedeutung von äquivalent, aber vielleicht hätte ich einen anderen Begriff wählen sollen um die Missverständnisse zu vermeiden 😉

    Aber is ja jetzt au egal=)

    Lg freeG


Log in to reply