这两个程序都是错误的。
如果没有范围内的原型,编译器会假定函数返回int
并采用未指定数量的参数。
让我们稍微改变一下你的文件:
$ cat func.c
double f(int a) {
return 1.0;
}
$ cat main.c
#include <stdio.h>
int main(void) {
double d = f();
printf("%lf\n", d);
return 0;
}
当我编译它时,gcc 会警告我(Visual C++ 也应该在一致模式下)。但是,让我们忽略警告。
$ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test
func.c:1: warning: unused parameter 'a'
main.c: In function 'main':
main.c:4: warning: implicit declaration of function 'f'
$ ./test
0.000000
它没有打印 1,而是打印了 0。这是因为编译器假定f()
返回 an int
,并且赋值d = f();
将 " int
" 转换为 a double
。编译器仍然编译了代码,因为它无法判断它f()
没有按照(隐式)声明的方式定义。但是标准不需要编译上述程序,因此编译器可能会拒绝它(gcc -Werror
例如尝试!)
如果我们将所有内容都放在一个文件中:
$ cat func.c >>main.c
$ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test
main.c:4: warning: implicit declaration of function 'f'
main.c: At top level:
main.c:9: error: conflicting types for 'f'
main.c:4: error: previous implicit declaration of 'f' was here
main.c:9: warning: unused parameter 'a'
现在编译器看到了冲突,并给你一个错误信息。但是,编译器不需要拒绝上述程序,它可能会也可能不会。
大多数编译器不会拒绝第一个程序,因为他们不知道您是否f()
在另一个翻译单元中对该函数进行了正确定义。他们拒绝第二个程序,因为他们知道你不这样做。