当我教 C 时,有时我指望 GCC 来做一些规则的“令人信服”的部分。例如,不应考虑函数上的局部变量在调用之间保留值。
GCC 总是帮助我向学生教授这些课程,将垃圾放在局部变量上,以便他们了解正在发生的事情。
现在,这段代码肯定让我很难受。
#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;
}
输出是:
(y=1, a=1), (y=2, a=2), (y=3, a=3), (y=4, a=4), (y=5, a=5),
但如果我评论这一行:
/* printf("(y=%d, ", y); */
然后输出变为:
a=1), a=32720), a=32721), a=32722), a=32723),
我使用 switch 编译代码-Wall
,但没有警告与使用局部变量相关,而没有初始化它们。
是否有任何 GCC 开关会导致警告,或者至少显式显示一些垃圾?我尝试了优化开关,这有助于代码输出变成这样:
$ 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),
但是 y=1 在所有情况下都是一种技巧。标准是否改变了,所以局部变量现在用零初始化?