Hallo,
bei meiner Suche habe ich herausgefunden, dass globale Variablen vor dem
ersten Aufruf von main initialisiert werden. Sehe ich das richtig, dass
analog dazu lokale Variablen nur vor dem ersten Aufruf einer Funktion
initialisiert werden und nicht bei jedem Funktionsaufruf immer wieder
neu?
Gruß,
Markus
Ich würde nicht davon ausgehen, dass jeder Compiler so nett ist, die
Variabeln automatisch zu initialisieren. Daher würde ich mir nicht
angewöhnen, dies dem Compiler und Zufall zu überlassen sondern es selbst
in die Hand nehmen und sofern nötig, selber initialisieren.
Ohne static werden sie überhaupt nicht initialisiert, es sei denn man
scheibt es explizit hin. Und das passiert im Prinzip genau dort wo es
steht, als Zuweisung in der Funktion bei jedem Durchlauf neu.
int i = 1;
entspricht also
int i; i = 1;
Da habe ich mich wohl falsch ausgedrückt. Ich initialisiere natürlich
meine Variablen selber.
Mich würde nur interessieren, ob die Zeile
int i = 0;
bei jedem Funktionsaufruf erneut ausgeführt wird, oder aber nur beim
ersten Funktionsaufruf. Aber jetzt wo ich drüber nachdenke, sollte die
Zeile bei jedem Funktionsaufruf erneut aufgerufen werden, da ja die
Variable bzw. der ihr zugeordnete Speicherplatz beim Verlassen der
Funktion wieder frei gegeben werden sollte. Ist das so richtig?
Markus schrieb:> Da habe ich mich wohl falsch ausgedrückt. Ich initialisiere natürlich> meine Variablen selber.
Globale Variablen werden immer initialisiert, auch wenn du es nicht
explizit hinschreibst.
> Mich würde nur interessieren, ob die Zeile> int i = 0;> bei jedem Funktionsaufruf erneut ausgeführt wird, oder aber nur beim> ersten Funktionsaufruf. Aber jetzt wo ich drüber nachdenke, sollte die> Zeile bei jedem Funktionsaufruf erneut aufgerufen werden, da ja die> Variable bzw. der ihr zugeordnete Speicherplatz beim Verlassen der> Funktion wieder frei gegeben werden sollte. Ist das so richtig?
Ja.
Hallo Markus,
lokale Variablen liegen auf dem Stack.
Da kann der Compiler gar nicht von selbst initialisieren, denn er weiß
nicht, wo die Variable während der Laufzeit liegen wird.
Ich habe in meinem Kurs ein kleines Video zu diesem Thema gedreht.
Vieleicht hilft das beim Verständnis:
http://et-tutorials.de/2276/funktionen-in-c-globale-und-lokale-variablen/
>Globale Variablen werden immer initialisiert, auch wenn du es nicht>explizit hinschreibst.
Nö.
Kann man bei manchen Compilern einstellen. Die tun dann vor die main()
noch ne Initialisierung rein. Dort wird dann der Speicher mit 0 gefüllt.
Ich glaube der GCC macht das . Beim Cosmic muss man ne crtsi.s
einbinden.
adfix schrieb:>> Globale Variablen werden immer initialisiert, auch wenn du es nicht>> explizit hinschreibst.>> Nö.
Dann ist's aber kein C, zumindest kein dem Standard entsprechendes.
adfix schrieb:>>Globale Variablen werden immer initialisiert, auch wenn du es nicht>>explizit hinschreibst.>> Nö.>> Kann man bei manchen Compilern einstellen. Die tun dann vor die main()> noch ne Initialisierung rein. Dort wird dann der Speicher mit 0 gefüllt.> Ich glaube der GCC macht das . Beim Cosmic muss man ne crtsi.s> einbinden.
Anders rum wird ein Schuh draus.
Globale Variablen werden immer auf 0 initialisiert. Manche Compiler
erlauben allerdings, mit speziellen Sprachmitteln, diese Initialisierung
abzuschalten. Dies kann ich als Programmierer benutzen, wenn ich von
vorne herein weiß, dass diese Initialisierung keinen Sinn macht und nur
Rechenzeitfresser ist.
Wenn der Cosmic das anders handhabt, ist er kein konformer C-Compiler.
Karl heinz Buchegger schrieb:> Globale Variablen werden immer auf 0 initialisiert. Manche Compiler> erlauben allerdings, mit speziellen Sprachmitteln, diese Initialisierung> abzuschalten. Dies kann ich als Programmierer benutzen, wenn ich von> vorne herein weiß, dass diese Initialisierung keinen Sinn macht und nur> Rechenzeitfresser ist.>> Wenn der Cosmic das anders handhabt, ist er kein konformer C-Compiler.
Ich bin mir sicher das laut ANSI C89, nur globale static Variablen mit 0
initalisiert werden. Globale Variablen die nicht static sind müssen
(sollen ) nicht initalisiert werden.
Vielleicht hat jemand von euch Zeit im Ansi C (89/99) Standart
nachzuschauen.
A. K. schrieb im Beitrag #1762542:
> Alle statische Variablen werden genullt. Ob global oder nicht.
Ja, ich meinte eigentlich das von den globalen Variablen nur die static
Variablen mit 0 initalisiert werden.
Was sind für dich nicht-statische globale Variablen?
Die Angabe "static" bedeuter zweierlei: Ausserhalb einer Funktion
definiert es nur die Sichtbarkeit (file scope statt external scope),
nicht hingegen die Art der Speicherung (statisch/stack). Innerhalb einer
Funktion definiert es neben der Sichtbarkeit (local scope) auch die Art
der Speicherung. Das ist nicht sonderlich logisch durchdacht, aber wo
ist C das schon.
Aber egal wie, solange die Variable statisch gespeichert ist, wird sie
genullt, unabhängig von der Sichtbarkeit.
Andersrum ausgedrückt: Ohne Initialisierung kommen nur lokale Variablen
der Speicherklassen "auto" (=default) und "register" aus. Alle anderen
werden genullt sofern nicht explizit initialisiert.
sepp schrieb:> Ich bin mir sicher das laut ANSI C89, nur globale static Variablen mit> 0 initalisiert werden. Globale Variablen die nicht static sind müssen> (sollen ) nicht initalisiert werden.
In C99 werden alle initialisiert. Ich bin mir relativ sicher, daß es in
C89 auch schon so war.
> Vielleicht hat jemand von euch Zeit im Ansi C (89/99) Standart> nachzuschauen.
Findet sich unter 6.7.8 Initialization:
1
If an object that has automatic storage duration is not initialized explicitly, its value is
2
indeterminate. If an object that has static storage duration is not initialized explicitly,
3
then:
4
— if it has pointer type, it is initialized to a null pointer;
5
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
6
— if it is an aggregate, every member is initialized (recursively) according to these rules;
7
— if it is a union, the first named member is initialized (recursively) according to these
8
rules.
Wobei man hier darauf achten muß, daß "static storage duration" hier
nichts mit dem Schlüsselwort "static" zu tun hat. Alle globalen
Variablen haben static storage duration.
Wolfgang Bengfort schrieb:> Hallo Markus,> lokale Variablen liegen auf dem Stack.> Da kann der Compiler gar nicht von selbst initialisieren, denn er weiß> nicht, wo die Variable während der Laufzeit liegen wird.
Natürlich weiss der Compiler, wie er an seine Variablen drankommt! Dazu
müssen sie dock keine zur Compilezeit (oder zur Link/Lokatezeit)
bekannte Adresse haben.
Wär ziemlich blöd, wenn er Variablen anlegt, auf die er nicht zugreifen
kann, weil er deren Adresse verschludert...
Nichtinitialisierte auto Variablen werden einfach deshalb nicht
initialisiert, weil es von C nicht spezifiziert ist, daß sie definierte
Werte haben müssen. Würde der Compiler Code zu deren Initialisierung
erzeugen, wäre er schlichtweg überflüssig.
Johann L. schrieb:>> Nichtinitialisierte auto Variablen werden einfach deshalb nicht> initialisiert, weil es von C nicht spezifiziert ist, daß sie definierte> Werte haben müssen. Würde der Compiler Code zu deren Initialisierung> erzeugen, wäre er schlichtweg überflüssig.
Hallo Johann,
wenn der Compiler die Variablen auf den Stack legt, kann er sie während
der Compilierzeit aber nicht initialisieren.
Weil vor dem Aufruf der Funktion auch schon etwas anderes auf dem Stack
gelegen haben kann. Das ist ja das Schöne am Stack.
Wolfgang Bengfort schrieb:>> Nichtinitialisierte auto Variablen werden einfach deshalb nicht>> initialisiert, weil es von C nicht spezifiziert ist, daß sie definierte>> Werte haben müssen. Würde der Compiler Code zu deren Initialisierung>> erzeugen, wäre er schlichtweg überflüssig.> Hallo Johann,> wenn der Compiler die Variablen auf den Stack legt, kann er sie während> der Compilierzeit aber nicht initialisieren.
Das ist ja kein Argument.
Der Compiler kann schliesslich auch Code einfügen, der nach dem Betreten
einer Funktion die neu geschaffenen Variablen initialisiert.
Beim Design der Sprache C wurde schlicht und ergreifend gesagt: Wollen
wir so nicht haben. Wenn der Programmierer eine lokale Variable
initialisieren will, dann soll er das hinschreiben. Und ansonsten halten
wir uns an die oberste Direktive: You don't get, what you didn't ask
for.
Der Programmierer hat keine Initialisierung verlangt, also kriegt er
auch keine.
Bei globalen Variablen hat man eine Ausnahme gemacht. Wohl deswegen,
weil sie in einem Programmlauf nur einmal zum Zuge kommt und daher
verschmerzbar ist, allerdings auch ein wenig Komfort bringt.
> auch schon etwas anderes auf dem Stack> gelegen haben kann
Die C-Sprachdefinition verlangt nicht, dass die zugrundeliegende
Maschine überhaupt so etwas wie einen Stack hat.
Karl heinz Buchegger schrieb:> Der Compiler kann schliesslich auch Code einfügen, der nach dem Betreten> einer Funktion die neu geschaffenen Variablen initialisiert.
Da haste Recht.
>> Die C-Sprachdefinition verlangt nicht, dass die zugrundeliegende> Maschine überhaupt so etwas wie einen Stack hat.
OK.
Ob der Frager auf diese Feinheiten hinaus wollte?
Karl heinz Buchegger schrieb:> Bei globalen Variablen hat man eine Ausnahme gemacht. Wohl deswegen,> weil sie in einem Programmlauf nur einmal zum Zuge kommt und daher> verschmerzbar ist, allerdings auch ein wenig Komfort bringt.
Wohl vor allem deswegen, weil bei
Multitasking/Multiuser-Betriebssystemen (C wurde ja ursprünglich für
Unix entwickelt) das System frisch angeforderten Speicher sowieso immer
löschen muss, damit nicht so ggf. sensitive Daten (aus der letzten
Benutzung des Speichers) leaken können. Sinnigerweise passiert das meist
dadurch dass der Speicher genullt wird.
Beim Programmstart ist der gesamte Speicher des Prozesses "frisch
angefordert", also sowieso genullt, und es kostet das Programm selbst
genau garnichts, alle statischen Variablen mit 0 zu initialisieren. Ergo
schreibt die Regel also eigentlich nur den Status Quo fest.
Andreas