以下代码有效:
int main()
{
void foo(int);
foo(3);
return 0;
}
void foo(a) int a;
{
printf("In foo\n");
}
但是这个没有:
int main()
{
void foo(float);
foo(3.24);
return 0;
}
void foo(a) float a;
{
printf("In foo\n");
}
为什么会这样?
以下代码有效:
int main()
{
void foo(int);
foo(3);
return 0;
}
void foo(a) int a;
{
printf("In foo\n");
}
但是这个没有:
int main()
{
void foo(float);
foo(3.24);
return 0;
}
void foo(a) float a;
{
printf("In foo\n");
}
为什么会这样?
这与 C 语言的演变以及它向后兼容旧版本的方式有关。
在这两种情况下,您都有一个 K&R 时代的定义foo()
,但之前有一个 C99 声明(带有原型)。
但在第一种情况下,int
实际上的默认参数是参数,所以函数调用是兼容的。
但是,在第二种情况下,K&R 定义引入了 K&R 时代的标准参数提升规则,并且参数的类型是真的double
。
但是,您在调用现场使用了现代原型,使其成为float
. 所以调用站点上的代码可能已经推送了一个真实的float
,在任何情况下它都是一个不同的类型double
。
如果所有的引用foo()
都是 K&R 风格,我相信你得到的最多将是一个警告,这就是编译器当时会做的事情,编译器必须这样做才能编译遗留代码。它甚至可能是一个类型安全的调用,因为浮点数都将被提升为双精度,至少对于过程调用接口是这样。(内部功能码不一定。)