[definition statische klassen member] windoof(cl) <-> schlimlux (gcc3.4)



  • Würde mich auch interessieren, denn der 8er schluckts:

    // a.cpp
    #include <iostream>
    using namespace std;
    
    class A {
    public:
    	static const int groesse = 10;
    	int ary[groesse];
    
    	void y() { cout << sizeof(ary)/sizeof(ary[0]) << endl; }
    };
    
    const int A::groesse;
    
    void y(int const& p);
    void y(int const* p);
    
    int main(int argc, char* argv[])
    {
    	A a;
    	a.y();
    	y(A::groesse);
    	y(&A::groesse);
    }
    
    // b.cpp
    #include <iostream>
    using namespace std;
    
    void y(int const& p) { cout << p << endl; }
    void y(int const* p) { cout << *p << endl; }
    

    Ausgabe: Drei mal 10.



  • sorry, hatte in der tat nirgends erwähnt, dann ich den VC8-compiler verwende. schande über mein haupt.
    genauer gesagt verwende ich den vc8 kompiler mit sp1. bei diesem wurde viel verschlimmbessert... also tatsächlich teils harte bugs implementiert (kann z.B. qt4.x nicht mehr ohne patch installieren).

    jedenfalls funktioniert das letzte beispiel von LordJaxom so wie er es aufgeührt hat. er definiert ja auch beide in der cpp! zumindest scheint der compiler sowas zu schlucken.

    aber es geht nicht wenn man aus

    // a.cpp
    

    eine header datei

    // a.h
    

    macht
    -->(vc8.0) main.obj : error LNK2005: "public: static int const A::groesse" (?groesse@A@@2HB) ist bereits in afile.obj definiert.
    Release\dummy.exe : fatal [man]error LNK1169: Mindestens ein mehrfach definiertes Symbol gefunden.[/man]



  • Man sollte auch nichts in einer Header-Datei definieren (einzige Ausnahme sind Templates und Inline-Funktionen). Da der Header in verschiedenen Übersetzungseinheiten eingebunden wird, hast du in jeder dieser Übersetzungseinheiten ein Exemplar deiner static-Variable - und das sind idR zu viele für den Linker.

    (Und ehe du hier mit "aber ich habe doh Include-Guards verwendet" kommst - die verhindern nur, daß der Header doppelt in eine Übersetzungseinheit eingebunden wird, gegen Linker-Probleme kannst du auf Präprozessor-Ebene nichts mehr machen)



  • @CStoll:
    In diesem Thread geht es doch gerade um die Möglichkeit, statische Memberkonstanten bereits in der Klasse mit Werten zu belegen!? 😕

    Oder ist das in ISO 14882:2003 wieder gestrichen worden? 😉



  • CStoll schrieb:

    (Und ehe du hier mit "aber ich habe doh Include-Guards verwendet" kommst - die verhindern nur, daß der Header doppelt in eine Übersetzungseinheit eingebunden wird, gegen Linker-Probleme kannst du auf Präprozessor-Ebene nichts mehr machen)

    😃 keine sorge. damit wäre ich schon nicht gekommen. aber man deklariert normalerweise auch keine klassen in der implementierungsdatei, oder?

    jedenfalls dreht man sich bei diesem problem einfach im kreis. zumal die compiler die sache eben anders interpretieren. möchte man also den code auf mehreren plattformen zum laufen bringen, so muss man eben mit kleinen "krücken" wie dem enum arbeiten... (um die noch viel schlimmeren #ifdefs zu vermeiden)

    LordJaxom schrieb:

    @CStoll:
    In diesem Thread geht es doch gerade um die Möglichkeit, statische Memberkonstanten bereits in der Klasse mit Werten zu belegen!? 😕

    Oder ist das in ISO 14882:2003 wieder gestrichen worden? 😉

    genau darum geht es...



  • LordJaxom schrieb:

    @CStoll:
    In diesem Thread geht es doch gerade um die Möglichkeit, statische Memberkonstanten bereits in der Klasse mit Werten zu belegen!? 😕

    Ja, mit Werten belegen kannst du sie auch bereits in der Deklaration - aber das const int a::groesse; hat trotzdem nichts im Header zu suchen.



  • okay, dann nochmal ausführlich (wollte mir doch nur ein paar zeilen sparen...)
    folgendes funktioniert mit dem vc8 compiler und scheinbar auch mit gcc3.5 und 4.x:

    // main.cpp
    #include <iostream>
    using namespace std;
    
    class A {
    public:
        static const int groesse = 10;
        int ary[groesse];
    
        void y() { cout << sizeof(ary)/sizeof(ary[0]) << endl; }
    };
    
    const int A::groesse;
    
    void y(int const& p) { cout << p << endl; }
    void y(int const* p) { cout << *p << endl; } 
    
    int main(int argc, char* argv[])
    {
        A a;
        a.y();
        y(A::groesse);
        y(&A::groesse);
    }
    

    folgendes jedoch zumindest mit vc8.0 sp1 nicht

    // a.h 
    #include <iostream> 
    using namespace std; 
    
    class A { 
    public: 
        static const int groesse = 10; 
        int ary[groesse]; 
    
        void y() { cout << sizeof(ary)/sizeof(ary[0]) << endl; } 
    }; 
    
    // a.cpp <-man sehe und staune ;-)
    const int A::groesse; 
    
    //main.cpp
    void y(int const& p) { cout << p << endl; }
    void y(int const* p) { cout << *p << endl; } 
    
    int main(int argc, char* argv[])
    {
        A a;
        a.y();
        y(A::groesse);
        y(&A::groesse);
    }
    

    und so hatte ich es auch gemeint... mit genau diesem code bekommt man mit vc8 eben linker fehler! denn er scheint den standard so auszulegen, dass mit "groesse=10" im header zugleich die definition von A::groesse erfolgte.
    dadurch kommt er beim linken mit a.obj natürlich in bedrängnis.



  • Ah ok. Aus der kompletten a.cpp darf man natürlich keine a.h machen. Ich ging davon aus dass muffmolch da selbsttätig selektiert hat 😉

    Muss ich später nochmal ausprobieren, momentan installiere ich meinen Arbeitsplatz gerade neu 😡



  • LordJaxom schrieb:

    Muss ich später nochmal ausprobieren, momentan installiere ich meinen Arbeitsplatz gerade neu 😡

    *lol* das problem kenn eich nur allzu gut. gestern erst habe ich meinen arbeitsspeicher auf 4Gb augerüstet, damit vista mit 8 instanzen von VS zurecht kommt. scheinbar ist d aber noch was anderes im argen. aber auf ne neuinstallation habe ich derzeit so gar keine lust *end-off topic*



  • muffmolch schrieb:

    ...mit genau diesem code bekommt man mit vc8 eben linker fehler! denn er scheint den standard so auszulegen, dass mit "groesse=10" im header zugleich die definition von A::groesse erfolgte....

    Hmmmm, besagte Dein Linkerfehler nicht, dass er keine Definition von A::groesse fand (und nicht, dass er 2 fand) ?

    Klingt jetzt blöd, aber vllt. machst Du da doch mit dem Linken was falsch ....
    falls nicht: Vergiß mein Post.

    Gruß,

    Simon2.


Anmelden zum Antworten