Wenn ich C unterrichte, zähle ich manchmal auf GCC, um den "überzeugenden" Teil einiger Regeln zu machen. Zum Beispiel sollte man nicht berücksichtigen, dass eine lokale Variable für eine Funktion den Wert zwischen den Anrufen beibehält.Die lokalen Variablen sind nicht statisch, aber warum bekomme ich dieses Verhalten?
GCC hat mir immer geholfen, diese Lektionen den Schülern beizubringen, indem sie lokalen Variablen den Müll auf den Kopf stellen, damit sie verstehen, was passiert.
Jetzt ist dieses Stück Code definitiv eine harte Zeit.
#include <stdio.h>
int test(int x)
{
int y;
if(!x)
y=0;
y++;
printf("(y=%d, ", y);
return y;
}
int main(void)
{
int a, i;
for(i=0; i<5; i++)
{
a=test(i);
printf("a=%d), ", a);
}
printf("\n");
return 0;
}
Die Ausgabe lautet:
(y=1, a=1), (y=2, a=2), (y=3, a=3), (y=4, a=4), (y=5, a=5),
Aber wenn ich die Zeile Kommentar:
/* printf("(y=%d, ", y); */
Dann ist der Ausgang werden:
a=1), a=32720), a=32721), a=32722), a=32723),
ich kompilieren den Code mit -Wall
wechseln, aber nicht warnen gs beziehen sich auf die Verwendung von lokalen Variablen, ohne sie zu initialisieren.
Gibt es einen GCC-Schalter, der eine Warnung auslöst oder zumindest etwas Müll anzeigt? Ich habe versucht, die Optimierungsschalter, und das half, da der Code Ausgabe wie folgt wurde:
$ gcc test.c -o test -Wall -Os
$ ./test
(y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1),
$ gcc test.c -o test -Wall -Ofast
$ ./test
(y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1),
$ gcc test.c -o test -Wall -O0
$ ./test
(y=1, a=1), (y=2, a=2), (y=3, a=3), (y=4, a=4), (y=5, a=5),
$ gcc test.c -o test -Wall -O1
$ ./test
(y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1),
$ gcc test.c -o test -Wall -O2
$ ./test
(y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1),
$ gcc test.c -o test -Wall -O3
$ ./test
(y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1), (y=1, a=1),
Aber y = 1 in allen Fällen Art Trick ist. Hat sich der Standard geändert, sodass die lokalen Variablen jetzt mit Nullen initialisiert werden?
Ich glaube nicht, dass C einen Standard für die Initialisierung von Variablen angibt. Tatsächlich denke ich, dass die Erinnerung so bleibt, wie sie ist. Wenn Sie also y hinzufügen, war der Wert von y derselbe wie zuvor und Sie erhöhen ihn dann. – Magn3s1um
Die Übereinstimmung ist, dass der zweite Aufruf der Funktion den gleichen Blockcode des RAM verwendet. –
Ich denke nicht, dass es ein Zufall ist, da der Compiler y zu einer bestimmten Region des Gedächtnisses verbindet, die relativ ist. Es ändert nicht die y-Relation zum ersten Stapel. Wenn also der vorherige Stapel nicht größer wird, ist y immer am selben Platz! – Magn3s1um