14

以下代码有效:

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");
}

为什么会这样?

4

1 回答 1

22

实际上,这是一个有趣的问题。

这与 C 语言的演变以及它向后兼容旧版本的方式有关。

在这两种情况下,您都有一个 K&R 时代的定义foo(),但之前有一个 C99 声明(带有原型)。

但在第一种情况下,int实际上的默认参数是参数,所以函数调用是兼容的。

但是,在第二种情况下,K&R 定义引入了 K&R 时代的标准参数提升规则,并且参数的类型是真的double

但是,您在调用现场使用了现代原型,使其成为float. 所以调用站点上的代码可能已经推送了一个真实的float,在任何情况下它都是一个不同的类型double

如果所有的引用foo()都是 K&R 风格,我相信你得到的最多将是一个警告,这就是编译器当时会做的事情,编译器必须这样做才能编译遗留代码。它甚至可能是一个类型安全的调用,因为浮点数都将被提升为双精度,至少对于过程调用接口是这样。(内部功能码不一定。)

于 2011-01-29T18:10:30.643 回答