mikrocontroller.net

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


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johnny B. (johnnyb)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: A. K. (prx)
Datum:

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

Autor: Markus (Gast)
Datum:

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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Markus (Gast)
Datum:

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

Autor: Wolfgang Bengfort (et-tutorials) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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-global...

Autor: adfix (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: sepp (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: sepp (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static storage duration is not initialized explicitly,
then:
   — if it has pointer type, it is initialized to a null pointer;
   — if it has arithmetic type, it is initialized to (positive or unsigned) zero;
   — if it is an aggregate, every member is initialized (recursively) according to these rules;
   — if it is a union, the first named member is initialized (recursively) according to these
       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.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Wolfgang Bengfort (et-tutorials) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Wolfgang Bengfort (et-tutorials) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Andreas Ferber (aferber)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.