mikrocontroller.net

Forum: Compiler & IDEs Variablenfreigabe for-Schleife


Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

ich habe z.B. eine for-Schleife:
for (int i=0;i<10;i++)
{...}

Wird dann nach dem Verlassen der Schleife der Speicherplatz von i wieder 
freigegeben, so wie in Funktionen?

Gruß
Richi

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Speicherplatz von Variablen wird (bei eingeschalteter Optimierung
natürlich) immer freigegeben, sowie die Variable nicht mehr benötigt
wird -- unabhängig von Schleifen, Blöcken, Funktionen etc.  In einem
derart einfachen Fall lebt die Variable sehr wahrscheinlich ohnehin
nur in einem Register.

Das physische Einräumen von Platz für Variable auf dem Stack erfolgt
dagegen nur funktionsweise.  Einmal allozierter Platz kann aber
innerhalb der Funktion für mehr als eine Variable benutzt werden.

Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, danke das wollte ich wissen!

Gruß
Richi

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch schrieb:
> Das physische Einräumen von Platz für Variable auf dem Stack erfolgt
> dagegen nur funktionsweise.

Sicher? Bezieht sich das nicht auf einen Anweisungsblock (das, was 
zwischen zusammengehörenden geschweiften Klammern steht)?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus t. Firefly schrieb:

>> Das physische Einräumen von Platz für Variable auf dem Stack erfolgt
>> dagegen nur funktionsweise.
>
> Sicher?

Guck dir mal den Code an.  Der Stackframe wird immer für die ganze
Funktion erzeugt.  Alles andere wäre vermutlich zu aufwändig.

Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmal dazu eine Frage:

Was ist wenn ich zuerst in einer Schleife i als int, in einer anderen i 
als long deklariere?

Gruß
Richi

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richard W. schrieb:
> Was ist wenn ich zuerst in einer Schleife i als int, in einer anderen i
> als long deklariere?

Dann hast du in einer Schleife einen int, in der anderen einen long. Die 
beiden habe nichts miteinander zu tun, da jedes i nur innerhalb seiner 
eigenen for-Schleife existiert.

WEnn die beiden Schleifen allerdings ineinander geschachtelt sind, 
beschwert sich der Compiler. Denn dann kommen sich die beiden 
Deklarationen in die Quere.

Oliver

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> WEnn die beiden Schleifen allerdings ineinander geschachtelt sind,
> beschwert sich der Compiler. Denn dann kommen sich die beiden
> Deklarationen in die Quere.

Kommt drauf an, an welcher Stelle genau das innere i definiert ist. Wenn 
als Schleifenzähler, dann hast du recht. Wenn innerhalb der {} der 
inneren Schleife, haben die nichts miteinander zu tun.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ganze ist sehr Compiler und Version abhängig.

Es gibt Compiler da existiert i noch nacht der Schleife und bei welchen 
nicht. Das Verhalten wurde soweit ich weiss in C99 erst festgelegt.
for (int i=0;i<10;i++)
{...}
i = 1;

sollte bei den aktuellen Compilern ein Fehler liefern, weil i nur 
innerhalb der {} gültig ist.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus t. Firefly schrieb:
>> Das physische Einräumen von Platz für Variable auf dem Stack erfolgt
>> dagegen nur funktionsweise.
>
> Sicher? Bezieht sich das nicht auf einen Anweisungsblock (das, was
> zwischen zusammengehörenden geschweiften Klammern steht)?

Verwechselst du hier eventuell den Scope auf C-Ebene mit der 
Implementation im Compiler? Die Variable existiert auf C-Ebene nur 
innerhalb der Klammern, aber das muß nicht bedeuten, daß der Speicher 
erst an der öffnenden Klammer bereitgestellt und genau an der 
schließenden Klammer wieder freigegeben wird.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> das ganze ist sehr Compiler und Version abhängig.
>
> Es gibt Compiler da existiert i noch nacht der Schleife und bei welchen
> nicht. Das Verhalten wurde soweit ich weiss in C99 erst festgelegt.

Davor war es gar nicht erlaubt, im Schleifenkopf die Variable zu 
definieren.

> for (int i=0;i<10;i++)
> {...}
> i = 1;
>
>
> sollte bei den aktuellen Compilern ein Fehler liefern, weil i nur
> innerhalb der {} gültig ist.

Bei jedem konformen Compiler sollte das einen Fehler produzieren. Bei 
C89 ist die Definition von i im Schleifenkopf nicht erlaubt, und bei C99 
ist i nur innerhalb der Schleife gültig.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> das ganze ist sehr Compiler und Version abhängig.

Nein. Ist es nicht. Das Verhalten ist immer eindeutig.

Peter schrieb:
> Es gibt Compiler da existiert i noch nacht der Schleife und bei welchen
> nicht.

Nein.

>for (int i=0;i<10;i++)

ist die Sichtbarkeit von i immer auf die for-Schleife beschränkt.
Das geht aber nur ab C99, ältere Versionen kompilieren das erst gar 
nicht.

Die Alternative wäre

>int i;
>for (i=0;i<10;i++)

dann ist die Sichtbarkeit von i völlig unabhängig von der for-Schleife, 
und i gibt es in dem gesamtem übergeordneten Sichtbarkeitsbereich, wie 
groß immer der auch ist. Das ist dann auch unter C99 so.

Oliver

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:
> Nein. Ist es nicht. Das Verhalten ist immer eindeutig.

nein, ist ja nicht so das ich mir das ausgedacht habe. Es gibt auch noch 
mehr Compiler als den GCC.
Das verhalten von 6er zum 7er Compiler von MS hat sich genau in diesem 
Punkt geändert. Ich durfte selber schon Code umschreiben wo es danach 
nicht mehr gingt.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> Es gibt auch noch
> mehr Compiler als den GCC.

Dann sind aber die, die es nicht so machen, buggy.

> Das verhalten von 6er zum 7er Compiler von MS hat sich genau in diesem
> Punkt geändert.

Naja, gerade MS ist ja nicht gerade berühmt für ihren Eifer, den
C99-Standard wirklich umzusetzen.

Zu ihrer Ehrenrettung muss man aber erwähnen, dass in einer frühen
Phase der Standardisierung des jetzigen C++-Standards tatsächlich
mal der Gültigkeitsbereich einer in der for-Anweisung deklararierten
Variablen hinter der for-Anweisung fortgesetzt worden ist.  Entsprechend
gab es auch mal eine GCC-Version, die das so implementiert hat, aber
meiner Erinnerung nach war das damals wirklich nur in C++ implementiert,
der C-Compiler vom GCC hatte das nie als Erweiterung -- außerdem ist
das alles schon 15 Jahre her.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:
> Peter schrieb:
>> Es gibt Compiler da existiert i noch nacht der Schleife und bei
>> welchen nicht.
>
> Nein.

Doch, die gibt es. Das ist zwar nicht ISO-konform, aber geben tut's das 
trotzdem. Der Compiler von Microsoft hat das lange Zeit so gemacht und 
macht's möglicherweise immer noch so. Dort fand man öfters als 
Work-Around für diesen Bug ein:
#define for if (0); else for

weil der Compiler dann den Scope der Variable auf das if beschränkt hat.
Das #define ist zwar auch nicht ISO-konform, aber man bekommt den 
Compiler damit zumindest dazu, den for-Scope richtig zu beachten.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> Oliver schrieb:
>> Nein. Ist es nicht. Das Verhalten ist immer eindeutig.
>
> nein, ist ja nicht so das ich mir das ausgedacht habe. Es gibt auch noch
> mehr Compiler als den GCC.

Nun ja, hier ganz oben drüber steht:
>Forum: GCC

Aber gut, ich verbessere mich:
Das Verhalten ist in C immer eindeutig definiert.

Das gilt natürlich nicht für Compiler, die eine C-ähnliche Syntax 
benutzen.

Oliver

Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, war mir nämlich nicht sicher ob das eine Fehlerquelle sein 
könnte, immer i zu verwenden.


Gruß
Richi

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.