statische felder -- mal wieder



  • Hallo zusammen,

    ich habe eine Klasse A, welche ein statisches Feld definiert, in dieser Art (A.h):

    class A {
            public:
    
                typedef unsigned int ResourceValue;
    
                static const ResourceValue MINIMUM_RESOURCE_VALUE = 0;
                A(const ResourceValue & rv);
    

    Nutzen möchte ich dies in einer Klasse B wie folgt:

    A a(A::MINIMUM_RESOURCE_VALUE);
    

    Compiliert wird, allerdings sagt mir der Linker:

    undefined reference to `A::MINIMUM_RESOURCE_VALUE'
    

    Was mach ich den schon wieder falsch?????

    Schon mal dank!



  • Du schaffst es nicht halbwegs ordentlichen Code hier zu posten, kann das sein?!
    Der Code hier ist so nicht im Ansatz kompilierbar (mit dem was ich mir grad dazu gespinnt habe, ist er das schon und auch noch fehlerfrei) und in deinem Thread mit den verschiedenen Timerklassen in einer Datenstruktur war der Beispielcode noch weit weit schlimmer.

    Naja, egal.

    class A {
    public:
    	typedef unsigned int ResourceValue;
    
    	static const ResourceValue MINIMUM_RESOURCE_VALUE = 0;
    	A(const ResourceValue & rv){}
    };
    
    int main()
    {
    	A a(A::MINIMUM_RESOURCE_VALUE);
    
    	return 0x0;
    }
    

    Ideone (und damit GCC) meckert nicht.

    Ist das der richtige Code?



  • Minimales, kompilierbares Beispiel ? Das was du bisher geschrieben hast lässt auf keinen Fehler schließen.



  • ok ok. Sorry jungs. 😃

    Also wenn ich dies hier baue:

    /*
     * File:   main.cc
     * Created on February 12, 2014, 11:05 AM
     */
    
    #include <cstdlib>
    
    using namespace std;
    
    class A {
    public:
    
        typedef unsigned int ResourceValue;
        static const ResourceValue MINIMUM_RESOURCE_VALUE = 0;
        static const ResourceValue MAXIMUM_RESOURCE_VALUE = 10000;
    
        A() {
        }
    
        A(const ResourceValue & rv) {
        }
    };
    
    /*
     *
     */
    int
    main(int argc, char** argv) {
    
        A newResources(A::MINIMUM_RESOURCE_VALUE);
        return 0;
    }
    

    Bekomme ich:

    mkdir -p build/Debug/GNU-Linux-x86
    rm -f "build/Debug/GNU-Linux-x86/main.o.d"
    g++    -c -g -MMD -MP -MF "build/Debug/GNU-Linux-x86/main.o.d" -o build/Debug/GNU-Linux-x86/main.o main.cc
    mkdir -p dist/Debug/GNU-Linux-x86
    g++     -o dist/Debug/GNU-Linux-x86/test build/Debug/GNU-Linux-x86/main.o 
    build/Debug/GNU-Linux-x86/main.o: In function `main':
    main.cc:43: undefined reference to `A::MINIMUM_RESOURCE_VALUE'
    collect2: ld returned 1 exit status
    gmake[2]: *** [dist/Debug/GNU-Linux-x86/test] Error 1
    

    Das ganze auf CentOs mit gcc(GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)

    Besser???



  • so gehts übrigends:

    int
    main(int argc, char** argv) {
    
        A::ResourceValue a = A::MINIMUM_RESOURCE_VALUE;
        A newResources(a);
        return 0;
    }
    

    😕



  • und auch so:

    [code="cpp"]
    class A {
    public:
    typedef unsigned int ResourceValue;

    static const ResourceValue MINIMUM_RESOURCE_VALUE = 0;
    A(const ResourceValue rv){} //<<<----
    };

    int main()
    {
    A a(A::MINIMUM_RESOURCE_VALUE);

    return 0x0;
    }
    [/cpp]

    Liegt es am typedef???





  • Du musst die statischen Member definieren.

    class A {
    public:
    
        typedef unsigned int ResourceValue;
        static const ResourceValue MINIMUM_RESOURCE_VALUE = 0;
        static const ResourceValue MAXIMUM_RESOURCE_VALUE = 10000;
    
        A() {
        }
    
        A(const ResourceValue & rv) {
        }
    };
    
    const A::ResourceValue A::MINIMUM_RESOURCE_VALUE;
    const A::ResourceValue A::MAXIMUM_RESOURCE_VALUE;
    


  • Furble Wurble schrieb:

    Du musst die statischen Member definieren.

    Bei integralen Datentypen nicht, soweit ich weiß.

    Sieht aus, als wäre der Compiler kaputt.



  • MFK schrieb:

    Sieht aus, als wäre der Compiler kaputt.

    Ich vermute der hat in dem Fall sogar recht.
    Wenn man die Referenz im Konstruktor entfernt, dann gehts.....


  • Mod

    MFK schrieb:

    Furble Wurble schrieb:

    Du musst die statischen Member definieren.

    Bei integralen Datentypen nicht, soweit ich weiß.

    Sieht aus, als wäre der Compiler kaputt.

    Nein, das ist ein "Feature" (andere würden es "Fehlerverschleierung" nennen) bestimmter Compiler. Andere Implementierungen melden hier streng nach ISO-Standard einen Fehler.



  • das ist ja in der art komisch.

    wie gesagt, ohne reference im konstruktor geht es. auch wie es Furble Wurble vorgeschlagen hat. was ist nun korrekt????

    @Skym0sh0 der link geht bei mir nicht. lädt ewig ohne das was kommt. was hätte man da gesehen?



  • ah, da war SeppJ schneller. also ist die variante von Furble Wurble die standard konforme?



  • MFK schrieb:

    Furble Wurble schrieb:

    Du musst die statischen Member definieren.

    Bei integralen Datentypen nicht, soweit ich weiß.

    Sieht aus, als wäre der Compiler kaputt.

    Ich versuch mich mal wieder am Standard 🙂

    9.4.2 Static data members
    2
    The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition.[...]

    3
    If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer [...] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

    somebody123 schrieb:

    MFK schrieb:

    Sieht aus, als wäre der Compiler kaputt.

    Ich vermute der hat in dem Fall sogar recht.
    Wenn man die Referenz im Konstruktor entfernt, dann gehts.....

    [Spekulation]Wahrscheinlich kriegt der Linker hier irgendwas zu fassen, wenn der Typ in der Signatur des C'tors auftaucht.[/Spekulation]



  • Skym0sh0 schrieb:

    Nix Fehler

    Ah: das ideone.com jetzt down ist, beendet meinen Beweis.
    q.e.d.

    😉



  • @sven_
    Die Variante mit Referenz und mit Definition ist OK.
    Die Variante ohne Referenz und ohne Definition ist auch OK.
    Nicht OK ist einzig die Variante mit Referenz aber ohne Definition. Denn dort wird das "Objekt" MINIMUM_RESOURCE_VALUE verwendet (Lvalue), nicht bloss der Wert (Rvalue). Und sobald das Objekt selbst verwendet wird, muss es auch definiert werden.

    Wobei viele Compiler sich trotzdem nicht an sowas stören.

    Ich finde diese Regel übrigens total doof. Technisch müssen Compiler bereits um Templates zu ermöglichen alles drauf haben, was nötig wäre, um die implizite Definition solcher static const zu ermöglichen.
    Also sollten sie es verdammtnochmal auch tun.


Log in to reply