I know it is wrong to use a function without prototype. But when I was fiddling around, I came across this strange and conflicting behavior.
test1
#include <stdio.h>
#include <limits.h>
void main(){
char c='\0';
float f=0.0;
xof(c,f);/* at this point implicit function declaration is
generated as int xof(int ,double ); */
}
int xof(char c,float f)
{
printf("%d %f\n", c,f);
}
Implicit function declaration would be int xof(int ,double );
error is
variablename.c:8:5: error: conflicting types for 'xof' int xof(char c,float f)
I understand this because implicitly generated function declaration (which defaults integer values to INT and decimals to DOUBLE) doesn't match the following function definition
test2
#include <stdio.h>
#include <limits.h>
void main(){
unsigned int a =UINT_MAX;
int b=0;
xof(a); /* implicit function declaration should be int xof(int); */
}
int xof(unsigned a,int b)
{
printf("%d %d\n", a,b);
}
implicit function declaration would be int xof(int); which should conflict with function definition
But this runs fine ( no error) and output is with 'a' behaving as 'int' value and 'b' has 'undefined Garbage'
-1 12260176
Could someone explain this. Thanks in advance.
When a function call is encountered without a definition, the implicit definition generated will always be int (*)()
, i.e. a function accepting an unspecified number of arguments and returning int
. The actual arguments in the function call are not taken into account. That is where your misconception comes from.
In the case of the first program, the generated error message is:
/tmp/x1.c:10: error: conflicting types for ‘xof’
/tmp/x1.c:10: note: an argument type that has a default promotion can’t match an empty parameter name list declaration
/tmp/x1.c:6: error: previous implicit declaration of ‘xof’ was here
The error appears because the actual function definition contains one or more parameters whose types are subject to default promotion rules. Specifically, any integer type with a rank lower than int
(a char
in this case) is promoted to int
in an expression. The same goes for the float
argument which gets promoted to a double
in expressions. In other words, it's impossible to pass parameters of the correct type to this function with an implicit declaration.
The second program doesn't generate an error because neither of the arguments (int
and unsigned int
) are subject to default promotion rules. In this case, you invoke undefined behavior because you aren't passing the proper number of arguments of the correct types. If you did pass in 2 parameters of the correct types, the behavior would be well defined.
Note that implicit function declarations are a C89 feature and are not supported in C99 and later, although some compilers may still accept them in C99 or C11 mode as an extension.