Header Fallen
-
Hallo
So, nun ein paar ernstere Fragen. Gehe ich richtig der Annahme, dass man bei Deklarationen im Header (welcher von anderen Units verwendet wird), gut aufpassen muss? Ich glaube viele sind sich garnicht bewusst, dass wenn sie z.B. eine Variable in einem Header deklarieren, diese dann (bei verwendung) in jeder *.cpp Unit eigenständig definiert wird. Das gewünschte Ergebnis wäre aber z.B. erst mit einer extern deklaration erreicht. Z.B. wenn jemand folgendes schreibt:
//header.h int i; //unit1.cpp #include "header.h" i = 1; //definition von i als eigenständige Variable //unit2.cpp #include "header.h" i = 2; //definition von i als eigenständige Variable. i von unit1.cpp ist immer noch auf 1.Jetzt ging man aber davon aus, da eine Deklaration bereits vorgenommen wurde, die definition auf diese direkt zugreift. Das ist aber falsch, stimmt doch oder? Man müsste hier also im Header die extern deklaration einleiten um den gewünschten Effekt zu erzielen, oder sehe ich das falsch?
Im Grunde ist eine Deklaration im header auch nichts anderes, als hätte man in unit1.cpp am anfang int i = 1; geschrieben oder? Der Unterschied an einem Header ist also nur der, dass man diese aus Sicht des Compilers nunmal in andere Units einbinden kann, sonst nichts anderes, ausser das Header grundsätzlich für Deklarationen verwendet werden.
Also muss man eigentlich immer gut aufpassen in wie fern man seine Header deklarationen verwenden möchte, oder nicht? Und noch eine Frage: Eine Deklaration ansich nimmt ja noch garkeinen Speicher ein (ich glaube es wird nicht einmal Assembler Code erzeugt), solange die Definition nicht erzeugt wurde, korrekt? Somit ist mit der Deklaration also nur der Typ und somit die Grösse klar. Ich frage das, weil wenn man nun in einem Header deklarationen hat und man dann in unterschiedlichen Units die Definition macht, wird eben jedesmal neuer Speicher verwendet, es sei denn die Deklaration ist extern und die Definition kommt in einer analogen Datei dann vor.
-
Hi,
nur ganz kurz: Ich bin ziemlich sicher, dass der Linker Dir das genau so als Fehler meldet.
Und allgemein: Sowas (1.) globale Variable & 2.) Variablendefinition in Header) macht man eben aus genau diesen Gründen nicht.
Gruß,
Simon2.
-
Das wichtige dabei ist, dass man sich im Klaren darüber ist, was eine Deklaration und was eine Definition ist. Bzgl Variablen kann man in Header-Dateien folgendes ohne Probleme schreiben:
extern int foo; // Deklaration einer Variablen mit externer Bindung extern const int zzz; // wie oben, nur unveränderlich const int bar = 32; // Definition einer Variablen mit interner BindungWas man dagegen nicht schreiben sollte ist
int k; // Definition mit externer Bindungda es dann die ODR (one definition rule) verletzt, sollte man diese Header-Datei in mehrere ÜEs einbinden und linken. Der Linker meckert üblicherweise in solchen Fällen.
Das gleiche gilt natürlich auch für Funktionen. Definitionen von Funktionen, die nicht inline sind, kein Funktionstemplate sind und auch keine interne Bindung haben, gehören nicht in Headerdateien rein.
Gruß,
SP