The following code works:
int main()
{
void foo(int);
foo(3);
return 0;
}
void foo(a) int a;
{
printf("In foo\n");
}
but this one does not:
int main()
{
void foo(float);
foo(3.24);
return 0;
}
void foo(a) float a;
{
printf("In foo\n");
}
Why does this happen?
Actually, kind of an interesting question.
This has to do with the evolution of the C language and the way it arranges to be backwards-compatible to the older flavors.
In both cases, you have a K&R-era definition for
foo(), but a C99 declaration (with prototype) earlier.But in the first case, the default parameter of
intactually is the parameter, so the function call is compatible.In the second case, though, the K&R definition brings in the standard argument promotions rule from the K&R era and the type of the parameter is really
double.But, you used a modern prototype at the call site, making it a
float. So the code at the call site might have pushed a realfloat, which is in any case a distinct type fromdouble.If all of the references to
foo()were K&R style, I believe the most you would get would be a warning, which is what compilers would have done back then, and the compiler must act like that to compile the legacy code. It would even have been a type-safe call because the floats would all be promoted to double, at least for the procedure call interface. (Not necessarily for the internal function code.)