da ich aber doch file3.h eh inkludiere, ist die Variable doch bekannt?
Warum muss dann noch ein extern davor?
Oder ist es nur als bessere übersicht, dass global_variable nicht nur in
file3.c benutzt wird?
felix schrieb:> da ich aber doch file3.h eh inkludiere, ist die Variable doch bekannt?> Warum muss dann noch ein extern davor?
Mit extern ist es eine Deklaration. es wird dem Compiler bekannt gegebn,
dass eine Variable mit dem Namen existiert.
Ohne extern ist es eine Definition.
Es wird eine Variable mit dem Namen angelegt.
Jede C-Datei, die diesen Header inkludiert, legt somit eine neue
Variable an.
Und damit hat der Linker ein Problem.
Dirk B. schrieb:> Jede C-Datei, die diesen Header inkludiert, legt somit eine neue> Variable an.
Genau: deklarieren darf man sooft man will (sofern die Deklarationen
gleich sind), definieren nur einmal. Das nennt sich ODR
(one-definition-rule): man muss genau einmal ein Konstrukt definieren,
nicht 0-mal und nicht >= 2-mal.
felix schrieb:> da ich aber doch file3.h eh inkludiere, ist die Variable doch bekannt?> Warum muss dann noch ein extern davor?
Genau darum. Mit extern machst du die Variable nur bekannt. Das ist was
anders, als sie zu erzeugen.
Mit
1
intglobal_variable=37;/* Definition checked against declaration */
sagst du dem Compiler: "Lege einen Integer mit Namen global_variable an,
halte den Speicher dafür vor und schreibe den Wert 37 rein."
Mit
1
externintglobal_variable;/* Declaration of the variable */
sagst du ihm dagegen: "Ach, übrigens, es existiert eine Variable vom Typ
int, und die heißt global_variable. Speicher ist dafür schon wo anders
angelegt worden."
Das Schlüsselwort "extern" besagt schlicht und ergreifend nur, dass die
Variable in einer anderen d.h. "externen" Datei definiert wird.
Deklaration = Typ und Namen der Variablen im Code angeben.
Definition = Der Variablen einen Wert verpassen.
Tipp:
Gehe sparsam mit solchen Variablen um, das kommt oft in Code vor der zu
viele globale Variablen nutzt, globale Variablen sind zu vermeiden wenn
es geht.
Vudoh schrieb:> Deklaration = Typ und Namen der Variablen im Code angeben.> Definition = Der Variablen einen Wert verpassen.
Nein. Nein.
Deklaration = Typ und Name der Variablen werden „nur“ bekannt gegeben
Definition = Die Variable wird angelegt (in C ist das gleichzeitung noch
eine Deklaration) Es wird Speicher verbraucht.
Initialisierung = erstmalige Wertzuweisung (bei der Definition)
Dirk B. schrieb:> Nein. Nein.>> Deklaration = Typ und Name der Variablen werden „nur“ bekannt gegeben> Definition = Die Variable wird angelegt (in C ist das gleichzeitung noch> eine Deklaration) Es wird Speicher verbraucht.> Initialisierung = erstmalige Wertzuweisung (bei der Definition)
Haarspalterei um die es hier nicht geht. Der TO wollte nur wissen was es
mit extern auf sich hat und das habe ich in meinem letzten Post deutlich
erklärt.
Das eine Deklaration keinen Speicher belegt, eine Definition dagegen
schon, das eine Initialisierung eine Erstzuweisung ist welche dazu führt
dass Speicher belegt wird sind Details die der TO hier nicht wissen
will.
Vudoh schrieb:> Haarspalterei um die es hier nicht geht. Der TO wollte nur wissen was es> mit extern auf sich hat und das habe ich in meinem letzten Post deutlich> erklärt.
eher undeutlich.
> Das eine Deklaration keinen Speicher belegt, eine Definition dagegen> schon,
ist der entscheidende Unterschied
> das eine Initialisierung eine Erstzuweisung ist welche dazu führt> dass Speicher belegt wird
Das passiert schon durch die Definition.
> sind Details die der TO hier nicht wissen> will.
Aber für dich ist es interessant, da du es falsch vermittelst.
Es wird schon wieder abgedriftet hier, je einfacher das Thema desto
schlimmer. Mein Rat an den TO ist, sich nicht in Details zu verlieren.
Daher fasse ich nochmal zusammen:
Das Schlüsselwort "extern" besagt schlicht und ergreifend nur, dass die
Variable in einer anderen d.h. "externen" Datei definiert wird.
So etwas sollte man vermeiden, denn es kommt meist in Code vor der zu
viele globale Variablen nutzt.
Um nochmal auf den Unterschied zwischen Deklaration und
Definition/Initialisierung hinzuweisen:
Eine Deklaration ist z.B. das hier und belegt keinen Speicher:
int zahl;
Ob extern davor steht oder nicht ändert nichts daran.
Eine Definition und automatisch auch eine Initialisierung ist z.B. das
hier:
int zahl = 10;
Oder andere Schreibweise:
int zahl {10};
Definition/Initialisierung reserviert Speicher.
Und noch eine Ergänzung: Deklarationen kann es beliebig viele von z.B.
ein und derselben Variable geben, deshalb kann sie ja auch in einer
Datei deklariert und in einer anderen definiert sein.
Vudoh schrieb:> Eine Deklaration ist z.B. das hier und belegt keinen Speicher:> int zahl;
Falsch: das ist eine Definition (ohne Initializer, was bedeutet, je
nachdem, static-storage oder nicht, ob eine zero-initialisation
stattfindet).
Vudoh schrieb:> Oder andere Schreibweise:> int zahl {10};
Und das geht so nur in C++, In C muss es:
Vudoh schrieb:> Eine Deklaration ist z.B. das hier und belegt keinen Speicher:> int zahl;
Nein.
Das ist eine Definition (mit impliziter Deklaration) und die belegt
schon Speicher.
> Ob extern davor steht oder nicht ändert nichts daran.
Das extern ändert es zu einer reinen Deklaration.
Die Initialisierung ist optional und nur bei einer Definition sinnvoll
und erlaubt.
Das extern ist ja nur bei globalen Variablen sinnvoll und die werden,
wenn nichts anderes angegeben wird, mit 0 initialisiert.
Man kann das extern auch bei der Deklaration von Funktionen mit angeben.
Aber da ist das redundant. Darum wird es i.A. weggelassen.
Vudoh schrieb:> Es wird schon wieder abgedriftet hier, je einfacher das Thema desto> schlimmer. Mein Rat an den TO ist, sich nicht in Details zu verlieren.
Und doch bist du derjenige, der immer diese Details anbringt, aber
leider falsch.
> Um nochmal auf den Unterschied zwischen Deklaration und> Definition/Initialisierung hinzuweisen:>> Eine Deklaration ist z.B. das hier und belegt keinen Speicher:> int zahl;> Ob extern davor steht oder nicht ändert nichts daran.
Das ist falsch! Mit extern ist es nur eine Deklaration, ohne ist es auch
eine Definition und belegt Speicher.
> Eine Definition und automatisch auch eine Initialisierung ist z.B. das> hier:> int zahl = 10;
Ob man explizit initialisiert oder nicht, ist egal für die Frage, ob es
eine Definition ist oder nicht.
> Oder andere Schreibweise:> int zahl {10};
Auch das ist in diesem Fall falsch, da das zwar für C++ gilt, nicht aber
für C, nach dem hier gefragt wurde. Das ist aber auch wieder so ein
Detail, das du nicht hättest anbringen müssen, nur um dich nachher
darüber zu beschweren, dass über nicht relevante Details diskutiert
wird.
Vudoh schrieb:> So etwas sollte man vermeiden, denn es kommt meist in Code vor der zu> viele globale Variablen nutzt.
Selbst das ist falsch, bzw ein eigenes Thema, dass hier wirklich keine
Rolle spielt.
Wenn Du eine Variable in 2 Files nutzt, dann sollte in einem Header ein
extern dazu sein. Wenn Du stattdessen eine Funktion nutzt, dann sollte
die auch in einem Header deklariert sein, braucht aber kein extern
davor. (Weil der Compiler das auch ohne extern am ; statt {} erkennen
kann.)
Dirk B. schrieb:> Vudoh schrieb:>> Eine Deklaration ist z.B. das hier und belegt keinen Speicher:>> int zahl;>> Nein.> Das ist eine Definition (mit impliziter Deklaration) und die belegt> schon Speicher.
Nein falsch. Wenn ich einen Namen einführe und dessen Typ angebe ist das
NUR eine Deklaration. Sobald ein Wert zugewiesen wird, wird Speicher
reserviert. Siehe Link von Wilhelm.
Ok jetzt muss ich mich aber öffentlich für mein Halbwissen was
Deklarationen und Definitionen angeht entschuldigen und ich entschuldige
mich auch bei allen die ich angegriffen habe!
Ich wollte wirklich kein Halbwissen verbreiten!
Hier ein Auszug aus einem Buch bzgl. EXTERN:
The extern keyword used in the second declaration of x simply states
that this
declaration of x isn’t a definition. It is rarely useful....usw.
Rolf M. schrieb:> Das ist falsch!
Stimmt, (fast) alles falsch!
Üblicherweise bindet man den header am Anfang ein, aber das muss nicht
sein. #include ... kann an beliebiger Stelle stehen und dann wird es
spannend.
Also: Wenn - was natürlich totaler Nonsens ist - eine Definition im
header seht und das #include innerhalb einer Funktion erfolgt ...
Nur einmal so für Euch Picometer-Messer.
MaWin schrieb:> Also: Wenn - was natürlich totaler Nonsens ist - eine Definition im> header seht und das #include innerhalb einer Funktion erfolgt ...
Es macht wenig Sinn, sich unkonventionelle Konstellation auszumalen. Dem
TO bringt das nichts, und Du und ich wissen so halbwegs, was wann
passiert und könnten es nutzen, bzw tun es vermutlich sogar. Der
Klassiker ist wohl das einbinden reiner Daten (cst) in eine
Datenstruktur. Sobald jemand weiss, was ein include macht, weiss er das.
Vudoh schrieb:> Siehe Link von Wilhelm.Vudoh schrieb:> Ok jetzt muss ich mich aber öffentlich für mein Halbwissen was> Deklarationen und Definitionen angeht entschuldigen und ich entschuldige> mich auch bei allen die ich angegriffen habe!
Nun weißt Du es besser ;-)
Was man Dir allerdings im Gegensatz zu vielen anderen hier zu Gute
halten muss, ist, dass Du das erkannt hast es auch hier sagst.
Das ist im echten Leben zwar normal aber hier in diesem Forum eher
selten. Wie auch hier die Unsitte verbreitet ist, alles nochmal selbst
zu wiederholen, auch wenn es von anderen schon längt genau so gesagt
worden ist.