使用没有原型的旧式函数的 C 编译器的行为
当我的程序由两个文件组成时:
main.c
#include <stdio.h>
int main(void) {
printf("%lf\n",f());
return 0;
}
func.c
double f(int a) {
return 1;
}
编译器不显示任何错误。
当我的程序仅包含一个文件:
main.c
#include <stdio.h>
int main(void) {
printf("%lf\n",f());
return 0;
}
double f(int a) {
return 1;
}
Visual C++ 2008 编译器显示以下错误:
Error 2 error C2371: 'f' : redefinition; different basic types d:\temp\projects\function1\function1\1.c 8 function1
任何人都可以解释这一奇怪的行为吗?
When my program consists of two files:
main.c
#include <stdio.h>
int main(void) {
printf("%lf\n",f());
return 0;
}
func.c
double f(int a) {
return 1;
}
compiler do not show any errors.
When my program consists of only one file:
main.c
#include <stdio.h>
int main(void) {
printf("%lf\n",f());
return 0;
}
double f(int a) {
return 1;
}
Visual C++ 2008 compiler show the following error:
Error 2 error C2371: 'f' : redefinition; different basic types d:\temp\projects\function1\function1\1.c 8 function1
Can anybody explain this strange behavior?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
C 将假设一个函数具有原型 int func();除非你另有说明。(请注意,在 C 中 int func(); 和 int func(void); 是不同的东西)
在第二种情况下,你调用
f()
,其中编译器没有看到任何原型,因此假设它是int f();
。稍后它会看到您对f()
的定义,它具有不同的原型 - 并发出错误。在 1. 情况下不会发生这种情况,因为它们位于不同的编译单元中。
C will assume a function has the prototype int func(); unless you have told it otherwise.(Note that in C int func(); and int func(void); are different things)
In your second case, you do a call to
f()
for which the compiler hasn't seen any prototype, so it assumes it isint f();
. Later on it sees your definition forf()
which has a different prototype - and issues an error.This doesn't happen in the 1. case, as they're in different compilation units.
这两个程序都是错误的。
如果范围内没有原型,编译器会假定函数返回 int 并采用未指定数量的参数。
让我们稍微更改一下您的文件:
当我编译它时,gcc 会警告我(Visual C++ 也应该如此,在一致模式下)。但让我们忽略这个警告。
它没有打印 1,而是打印 0。这是因为编译器假设
f()
返回一个int
,并且赋值d = f();
将“int
”转换为double
。编译器仍然编译代码,因为它无法判断f()
没有按照(隐式)声明的方式定义。但是标准并不要求编译上述程序,因此编译器可能会拒绝它(例如尝试使用 gcc -Werror!)如果我们将所有内容都放在一个文件中:
现在编译器会看到冲突,并给出错误消息。但是,编译器不需要拒绝上述程序,它可能会也可能不会。
大多数编译器不会拒绝第一个程序,因为它们不知道您在另一个翻译单元中是否有正确的函数
f()
定义。他们拒绝第二个计划,因为他们知道你不知道。Both the programs are wrong.
Without a prototype in scope, a compiler assumes that a function returns
int
and takes an unspecified number of parameters.Let's change your files a bit:
When I compile it, gcc warns me (Visual C++ should too, in conformant mode). But let's ignore the warning.
It did not print 1, but printed 0. This is because the compiler assumed that
f()
returned anint
, and the assignmentd = f();
converted that "int
" to adouble
. The compiler still compiled the code because it couldn't tell thatf()
wasn't defined the way it was (implicitly) declared. But compiling the above program isn't required by the standard, so the compiler could have rejected it (try withgcc -Werror
for example!)If we have everything in one file:
Now the compiler sees the conflict, and gives you an error message. But, a compiler is not required to reject the above program, it may or may not.
Most compilers don't reject the first program because they don't know if you have a correct definition of the function
f()
in another translation unit or not. They reject the second program because they know that you don't.您的第一个示例从不使用
func.c
所以我不确定编译器对f()
做了什么,因为它没有定义。在第二个示例中,我不知道为什么不能有两个具有不同签名的函数,但您没有调用您定义的函数。您可以不带参数调用
f()
,但您定义的f
采用 int,这使其成为不同的函数。Your first example never uses
func.c
so I'm not sure exactly what the compiler is doing aboutf()
because it has no definition.In the second example, I don't know why you can't have two functions with different signatures, but you aren't calling the function you've defined. You call
f()
with no arguments, but thef
you define takes an int which makes it a different function.