static class und Übersetzungseinheiten



  • Hallo,

    folgendes sei gegeben:

    test.h

    struct test
    {
       static userdefined_class; // Ersatz einer globalen Variablen
    }
    

    Nun wird mittels

    test::userdefined_class

    in verschiedensten Einheiten (einheit1.cpp form1.cpp keineahnungwas.cpp nochnegroßeunit.cpp) verwendet.

    Ist hier gewährleistet das userdefined_class immer das gleiche Objekt ist ?

    Bei:

    test2.h

    int global;
    

    kann es ja passieren, das jede Unit ihre eigene Version hat. Wie schaut das bei obrigen Konstrukt aus ?



  • Hi,

    ich würde tippen, dass es (analog zu Deinem int-Beispiel) davon abhängt, ob Du in einer Übersetzungseinheit per "extern" das Objekt in der anderen Unit referenzierst oder ein neues definierst.

    Also:
    a)

    // In a.cpp:
    int global; // lege ein int an
    
    // in b.cpp
    int global; // lege ein int an
    

    gibt beim Linken vermutlich einen "duplicate symbol"-Fehler o.ä., während

    // In a.cpp:
    int global; // lege ein int an
    
    // in b.cpp
    extern int global; // beziehe Dich auf ein int, das woanders angelegt wurde
    

    dafür sorgt, dass in b.cpp sozusagen nur mit einer Referenz (die allerdings erst der Linker auflöst) auf das a.cpp::global-int" gearbeitet wird.

    Ein bischen Schwierigkeiten macht mir bei Deinem Beispiel, dass in C "static" ja auch "internal linkage" bedeutet, was automatisch einen "Verweis per extern" ausschließt .... aber da hat sich C++ evtl. geändert.

    Gruß,

    Simon2.



  • Ja, nun wird aber keine Instanz der Klasse angelegt sondern mittels

    test::userdefined_class zugegriffen



  • Knuddlbaer schrieb:

    Ja, nun wird aber keine Instanz der Klasse angelegt sondern mittels

    test::userdefined_class zugegriffen

    Allerdings muß der Linker auch eine entsprechende Definition finden - so mußt Du in Deinem Beispiel ja irgendwo auch ein

    int test::userdefined_class;
    

    in einer Unit aufnehmen.

    ... und ich vermute deswegen, dass Du mit einer Deklaration (in der "zweiten" Unit) wie

    extern int test::userdefined_class;
    

    klarkommst.
    aber ich habe noch nicht ausprobiert/nachgeschlagen, ob das (so) funktioniert (wie ich mir das vorstelle).

    Gruß,

    Simon2.

    P.S.: Irgendwie ist mir noch nie aufgefallen, dass es hier in C auch sowas wie eine "C++-Referenz" gibt. 😃



  • Knuddlbaer schrieb:

    Ist hier gewährleistet das userdefined_class immer das gleiche Objekt ist ?

    genauso wie bei

    test2.h

    int global;
    

    ist immer garantiert dass es 1 objekt nicht doppelt geben kann. Das verlangt die ODR.

    kann es ja passieren, das jede Unit ihre eigene Version hat. Wie schaut das bei obrigen Konstrukt aus ?

    nein, kann nicht passieren.

    man kann aber natuerlich jeder UeE eine eigene global variable geben, indem man sie in einen unnamed namepace packt.. aber das wird dann echt haesslich.

    eine deklaration ala
    extern int foo::bar;
    braucht man uebrigens nicht. foo::bar ist in der klassendefinition von foo bereits deklariert.



  • Mal nebenbei:

    struct test
    {
       static userdefined_class; // Ersatz einer globalen Variablen
    }
    

    Fehlt hier nicht der Name der Variablen, die den Typ userdefined_class haben soll (oder der Typ der Variablen, die userdefined_class heisst)?



  • Shade Of Mine schrieb:

    ...
    eine deklaration ala
    extern int foo::bar;
    braucht man uebrigens nicht. foo::bar ist in der klassendefinition von foo bereits deklariert.

    Jupp, habe ich auch gerade festgestellt.

    Ist auch klar - habe mir irgendwie selbst mit dem "int global" und dem "extern" ein Bein gestellt.
    Aber da ein struct/class uns die Möglichkeit gibt, zwischen Deklaration und Definition/Instantiierung zu unterscheiden, braucht's das gar nicht mehr explizit (im Gegensatz zum "int global")....

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Aber da ein struct/class uns die Möglichkeit gibt, zwischen Deklaration und Definition/Instantiierung zu unterscheiden, braucht's das gar nicht mehr explizit (im Gegensatz zum "int global")....

    bei einer "normalen varialen definition" kann man auch problemlos zwischen deklaration und definition unterscheiden:

    int global; //definition
    extern int global; //deklaration
    

    genauso wie bei einer klasse:

    class C; //deklaration
    class C {}; //definition
    

    bei einer static variable innerhalb einer klasse auch:

    class C{
    static int foo; //deklaration
    };
    int C::foo; //definition
    


  • Shade Of Mine schrieb:

    Simon2 schrieb:

    Aber da ein struct/class uns die Möglichkeit gibt, zwischen Deklaration und Definition/Instantiierung zu unterscheiden, braucht's das gar nicht mehr explizit (im Gegensatz zum "int global")....

    bei einer "normalen varialen definition" kann man auch problemlos zwischen deklaration und definition unterscheiden:

    int global; //definition
    extern int global; //deklaration
    

    ...

    Eben ! Wie ich gesagt habe: Per "extern" unterscheidet man explizit die Deklaration von der Definition.

    und deswegen auch andersherum: Weil ein

    struct {
        static int a;
    } A;
    

    in C++ eine reine Deklaration ist, braucht man hierbei kein "extern" mehr, um diese Tatsache auszudrücken.

    Gruß,

    Simon2.


Anmelden zum Antworten