When I teach C, sometimes I reckon that the GCC will fulfill the “convincing” part of some rules. For example, you should not consider that a local variable in a function stores a value between calls.
GCC has always helped me teach these lessons to students by putting garbage in local variables so that they understand what is going on.
Now this piece of code is definitely causing me a tough time.
#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; }
Output:
(y=1, a=1), (y=2, a=2), (y=3, a=3), (y=4, a=4), (y=5, a=5),
But if I comment out the line:
/* printf("(y=%d, ", y); */
Then the conclusion will be:
a=1), a=32720), a=32721), a=32722), a=32723),
I will compile the code using -Wall , but no warnings are associated with using local variables without initializing them.
Is there any GCC switch to trigger a warning, or at least explicitly show some kind of garbage? I tried the optimization switches, and that helped, as the code output became something like this:
$ 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),
But y = 1 in all cases is a kind of trick. Is the standard changed, so local variables are now initialized to zeros?