Global, Modulglobal, Lokal
-
freakC++ schrieb:
und woher "weiß" externjetzt, auf welche Variable (auf welches a) es verweist?
Vielen Dank´
lg, freakC++Probier doch mal aus was bei mehreren Definitionen passiert...
-
@freak: Ganz am Anfang hast Du von "Sichtbarkeit" gesprochen und da hätte man eigentlich nen Fragenzeichen druntersetzen müssen. Wenn in einer ÜE etwas mit externer Bindung definiert wird, ist das dem Compiler, wenn er eine andere ÜE übersetzen will, nicht ohne weiteres bekannt. Dafür gibt es ja die Deklarationen, die man üblicherweise in Header-Dateien reinschreibt.
-
freakC++ schrieb:
und woher "weiß" externjetzt, auf welche Variable (auf welches a) es verweist?
Vielen Dank´
lg, freakC++Der Compiler weiß das gar nicht (wenn er Unit2.cpp übersetzt). Er erstellt vielmehr eine "externe Referenz", die dann der Linker auflöst. Aus diesem Grund übersetzt der Compiler TUs mit "extern"-Verweisen auch dann klaglos, wenn die referenzierte Variable nirgens definiert wird. Erst der Linker mach in einem solchen Fall Rabatz.
Der ganze Zauber daran ist ja erst die Überwindung der Grenzen von Translation Units.
Stefan.
-
freakC++ schrieb:
und woher "weiß" extern jetzt, auf welche Variable (auf welches a) es verweist?
Klammere Dich nicht an einzelne Schlüsselwörter. Die Konzepte (Bindung, Decl vs Def) dahinter sind wichtig. Da gibt es leider keine 1:1 Beziehung. Mit extern kannst Du eine externe Bindung erzwingen und sogar u.U. aus einer Definition eine Deklaration machen. Vieles hat aber auch ohne das Schlüsselwort schon eine externe Bindung.
Bzgl "welches a": Es kann nur ein a mit externer Bindung geben. Definierst Du zwei, schimpft der Linker "multiple definition of ..." (oder so ähnlich). Deklarierst Du nur und definierst nie, schimpft der Linker "undefined reference to ..." (oder so ähnlich). Der Linker ist der, der die ÜEs zusammenknotet. Er schaut sich die Kompilate der ÜEs an. In einem steht vllcht. "Ich habe ein A" (in Form einer Symboltabelle oder so). In einem anderen steht vielleicht "ich brauche ein A". Namen für Dinge mit interner Bindung interessieren den Linker weniger.
Gruß,
SP
-
Hallo,
achso...ähmm noch eine Sache zum zweiten Post von SeppJ. Du schreibst, dass es eben nicht geht, wenn ich die Unit inkludiere.
Ich habe jetzt mal mit Borland Builder 6 zwei Units erstellt und in einer eine gloable Variable erstellt. Wenn ich jetzt die eine in die
andere inkludiere, dann ist die Variable bekannt.Warum soll das dann deiner Ansicht nicht funktionieren? Habe ich dich da falsch verstanden?
Vielen Dank
lg, freakC++
-
Beim
#include
führt der Preprocessor nur eine einfache Textersetzung durch -- wie schon mehrfach erwähnt. Dem eigentlichen Compiler ist es egal, aus welchen Dateien die ÜE (Übersetzungseinheit) zusammengesetzt wird.Schreibst Du
//---- dings1.cpp ---- int i; // Definition //---- dings2.cpp ---- #include "dings1.cpp" int main() { return i; }
hast Du folgende ÜEs:
//----- ÜE1 (dings1.cpp) ----- int i; //----- ÜE2 (dings1.cpp in dings2.cpp eingefügt) ----- int i; int main() { return i; }
Hier enthält jede ÜE eine Definition von i --> Die ÜEs kannst Du also nicht linken (multiple definition of 'i').
Vielleicht recherchierst Du nochmal nach Preprocessor, Compiler und Linker. Vielleicht liest Du Dir auch nochmal den kompletten Thread durch. Einiges scheint Dir entgangen zu sein. Vielleicht besorgst Du Dir auch mal ein gutes Buch. Wenn Du Dein Alter und/oder Erfahrungsstand verrätst, kann man Dir vielleicht nen guten Buchtipp geben.
Das, was Du vielleicht willst, sieht so aus:
//---- dings.hpp ----- #ifndef MEINE_DINGS_KOPFDATEI_GUARD #define MEINE_DINGS_KOPFDATEI_GUARD extern int i; // Deklaration #endif // Include-Guard endet hier //---- dings.cpp ----- #include "dings.hpp" // nicht notwendig aber üblich und löblich //double i = 99; // würde wegen der Deklaration in dings.hpp // zu einem Fehler führen int i = 99; // Definition von i ist konsistent zur Deklaration //---- haupt.cpp ----- #include <iostream> #include "dings.hpp" int main() { std::cout << i << '\n'; // i wegen der Deklaration in dings.h bekannt. }
Gruß,
SP
-
ich hab neulich auch ne version gesehen, wo man die *.cpp nicht brauchte, ging so in etwa:
#ifdef GUARD #define EXTERN extern #endif #define GUARD EXTERN int i; #undef EXTERN
habs mir aber nicht genau angeguckt, weil ichs zu unübersichtlich fand...
bb
-
unskilled schrieb:
ich hab neulich auch ne version gesehen, wo man die *.cpp nicht brauchte, ging so in etwa:
#ifdef GUARD #define EXTERN extern #endif #define GUARD EXTERN int i; #undef EXTERN
habs mir aber nicht genau angeguckt, weil ichs zu unübersichtlich fand...
bb
Das klappt nicht.
Das kann nur absichern, daß die Definition nur einmal pro Übersetzungseinheit da ist. Dazu würde es völlig reichen, sie normal in den Header zu schreiben, dank include guards.Was klappt, ist ne andere Version:
#ifdef VON_DER_MAIN_INLUDIERT int i; #else extern int i; #endif
Sowas habe ich sogar mal geschrieben. Ich rate davon ab.
-
Persönlich finde ich, dass nur ein fehlgeschlagenes design extern benötigt, ich war noch nie in der situation wo ich es brauchte. Kann mir mal jemand ein beispiel geben, wo man so etwas brauchen könnte?
Gruß
-
jesus was black schrieb:
Persönlich finde ich, dass nur ein fehlgeschlagenes design extern benötigt, ich war noch nie in der situation wo ich es brauchte. Kann mir mal jemand ein beispiel geben, wo man so etwas brauchen könnte?
Gruß"brauchen" ist aber ein hartes wort. ich kann jede globale variable als Singleton tarnen.
-
Hallo,
vielen Dank für die vielen Antworten. Auch wenn sich meine Fragen manchmal ein bisschen überschneiden, dann bin dennoch über jede Antwort froh.@SP: Ich bin 17 Jahre alt und bringe mit C++ alleine bei (da ich keinen kenne, der diese Sprache auch leidenschaftlich kann/lernt.) Ich habe mir ein gutes Buch gekauft (C++ lernen und professionell anwenden von Ulla Kirch Prinz und Peter Prinz). Die Sache ist einfach nur, dass ich schon mehrere Bücher durchgearbeitet habe und dieses mein erstes "professionelles" ist. Die davor waren immer "für Kids" etc. Ich arbeite die Kapitel durch und
schreibe alle Fragen aus, recherchiere im Internet und frage schließlich euch, da ihr die einzigen seit, die mir helfen könnt. Dies mache ich hauptsächlich in den Ferien, weshalb meine Postanzahl in den Ferien immer rapide steigtIch danke euch für eure Hilfe und bitte euch über die eine oder andere indirekt wiederholte oder auch nicht so kluge Frage hinwegzusehen!
Ich finde dieses Forum echt super!
Bis dann
lg, freakC++