FAQ Fehler, pumuckl ?
-
Zeus schrieb:
Siehe:http://www.c-plusplus.net/forum/viewtopic-var-t-is-246875.html
Ich zitiere diese FAQ:
Bei statischen Klassenvariablen muss in der Übersetzungseinheit eine Definition existieren. Für integrale Typen kann dies gleich in der Klassendefinition geschehen, alle anderen Typen müssen außerhalb der Klasendefinition definiert werden:
//foo.h struct foo { static int i = 5; //Deklaration + Definition einer integralen statischen Variable static std::string s; //Deklaration }; //foo.cpp std::string foo::s = "statisch!"; //Definition in der .cpp
Das ist nicht ganz richtig. Die Zeile "static int i = 5;" ist keine Definition. Sie ist nichtmal legal. Der GCC gibt mir folgende Fehlermeldung:
error: ISO C++ forbids in-class initialization of non-const static member ‘i’
Auch i muss außerhalb der Klasse definiert/initialisiert werden. C++ erlaubt aber das Weglassen einer Definition für Konstanten von "Literaltypen" (nicht nur integrale Typen). ZB so etwas:
//foo.h struct foo { static const float p = 3.14; // Deklaration };
Solange nur der Wert von p benutzt wird, ist keine Definition nötig. Hole ich mir irgendwann einen Zeiger auf das p-Objekt oder binde p an eine const-ref, wird eine Definition fällig. Fehlt diese Definition, wird es eine "undefined reference"-Fehlermeldung vom Linker geben; denn diese in-class Initialisierung ist keine Definition.
kk
-
ISO/IEC 14882 §9.4.2 Absatz4 schrieb:
If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.
Ich denke das Fragezeichen kann weg. Da müsste pumuckel definitiv nochmal drübersehen.
-
Danke für den Hinweis, habs korrigiert. Ging natürlich nur um statische integrale Konstanten.
-
Ok, jetzt steht dort aber immer noch, dass es eine Definition sei, wohingegen der Standard nur von "in-class initializer" spricht und ausdrücklich per "The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer." eine Definition einfordert, falls das Objekt außerhalb von konstanten Ausdrücken "genutzt" wird.
Ich hatte mich wohl vertan, was die Typen angeht. Erst C++0x wird alle "Literaltypen" hier unterstützen.
-
Auch hier muss man krümelkacker Recht geben, den der Beitrag spricht ja sogar speziell über Linkfehler und "undefined reference".
Schnell! Schnell! Bevor das noch jemand sieht ...