Forum: Compiler & IDEs Variablenfreigabe for-Schleife


von Richard W. (richi)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Richard W. (richi)


Lesenswert?

OK, danke das wollte ich wissen!

Gruß
Richi

von Rufus Τ. F. (rufus) Benutzerseite


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)?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Richard W. (richi)


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

von Oliver (Gast)


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

von der mechatroniker (Gast)


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.

von Peter (Gast)


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.
1
for (int i=0;i<10;i++)
2
{...}
3
i = 1;

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

von Rolf Magnus (Gast)


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.

von Rolf Magnus (Gast)


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.

von Oliver (Gast)


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

von Peter (Gast)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Rolf Magnus (Gast)


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:
1
#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.

von Oliver (Gast)


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

von Richard W. (richi)


Lesenswert?

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


Gruß
Richi

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.