尝试编译以下代码片段时:
#include <stdio.h>
#include <time.h>
void change_a(int * a) {
*a = 1;
return;
}
void main(void) {
int a = 0;
change_a(&a);
if (a) {
time_t start = time(NULL);
}
/* do something that never mentions a */
if (a) {
time_t end = time(NULL);
printf("Time spent = %ld\n", (int) end - start);
}
}
GCC声明start
行中printf
变量未定义:
$ gcc --version
gcc (Debian 4.8.2-1) 4.8.2
[SNIP]
$ gcc -o test.bin test.c
test.c: In function ‘main’:
test.c:24:44: error: ‘start’ undeclared (first use in this function)
printf("Time spent = %ld\n", (int) end - start);
另一方面,当将main函数更改为:
时,它可以编译并正常工作void main(void) {
int a = 0;
time_t start = 0;
change_a(&a);
if (a) {
start = time(NULL);
}
...
我做错了什么,或者编辑做了一件我不知道的搞笑事情?
我认为可能是编译器过于聪明并且优化了这段代码或者在其启发式或其他方面出现故障。但每隔一次我“发现编译器错误”总是我错过了一些非常明显的错误。
因此,在我指责其他聪明人不那么聪明之前,我宁愿聪明的人检查一下。特别是在没有优化的情况下也会发生问题:
$ gcc -O0 -o test.bin test.c
test.c: In function ‘main’:
test.c:24:44: error: ‘start’ undeclared (first use in this function)
printf("Time spent = %ld\n", (int) end - start);
^
test.c:24:44: note: each undeclared identifier is reported only once for each function it appears in
我还想知道是否有更好的方法可以避免编译错误(如果不是最后一个代码段中的解决方法)。如果我的代码错误(因为响应将包含“正确的”代码),这很明显,但我也想知道如何在某人修复GCC中的(涉嫌)错误时避免错误。< / p>
答案 0 :(得分:6)
在第一个示例中,start
变量在if
语句的范围内声明。因此,变量超出了代码块末尾的范围(结束大括号}
)。这绝对不是编译器错误。
您的“解决方法”是正确的解决方案。
See here有关变量作用域如何在C / C ++(以及许多其他使用C样式作用域的语言)中工作的更全面描述。
答案 1 :(得分:0)
也许“开始”范围是在
if (a) {
time_t start = time(NULL);
}
start是不能参考if block