Forum: PC-Programmierung C: Wann werden lokale Variablen initialisiert?


von Markus (Gast)


Lesenswert?

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

von Johnny B. (johnnyb)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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;

von Markus (Gast)


Lesenswert?

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?

von (prx) A. K. (prx)


Lesenswert?

Richtig. Und bei
  while (1) {
    int i = 1;
    ...
  }
passiert das bei jedem Durchlauf.

von Markus (Gast)


Lesenswert?

OK, danke A.K. Hab so lange zum tippen gebraucht und Deine Antwort erst 
danach gelesen.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Markus (Gast)


Lesenswert?

Ja, das mit den globalen Variablen habe ich gerade in einem anderen 
Thread gelesen.
Danke euch für die superschnellen Antworten!

von Wolfgang B. (et-tutorials) Benutzerseite


Lesenswert?

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/

von adfix (Gast)


Lesenswert?

>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.

von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von sepp (Gast)


Lesenswert?

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.

von sepp (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Wolfgang B. (et-tutorials) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Wolfgang B. (et-tutorials) Benutzerseite


Lesenswert?

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?

von Andreas F. (aferber)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.