How to handle implicit function parameters?

From GNU Tools - Wiki
Revision as of 21:22, 24 April 2017 by Administrator (Talk | contribs) (handle implicit function parameters)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

How to handle implicit function parameters?

According to "The C programming language" by Brian Kernighan and Dennis Ritchie:

If a function, and the call to it, have inconsistent types in the same source file, the error will be detected by the compiler.

However, if (as it is more likely) the function were in another module (file) and it were compiled separately, the mismatch would not be detected. So instead of the function returning its type, the compiler would treat that type as an int, and meaningless outcome would result.

The reason a mismatch can happen is that if there is no function prototype, so the function is implicitly declared by its first appearance in an expression, such as:

 x = foo(y);

If a name that has not been previously declared occurs in an expression and is followed by a left parenthesis, it is declared by context to be a function name. The function is assumed to return an int, and nothing is assumed about its arguments. Furthermore, if a function declaration does not include arguments, as in:

 x = foo();

that too is taken to mean that nothing is to be assumed about the function arguments, resulting in all parameter checking being turned off. This special meaning of the empty argument list is intended to permit older C programs to compile with new compilers. It is however a bad idea to use it with writing new programs. As a general rule - if the function takes arguments, declare them; if it takes no arguments, use void.

For example: Having 2 files, test1.c and test2.c;

test1.c containing the main:

 #include <stdio.h>
 int main()
 {
 	char x[] = "3.14\0";
 	double bar = foo(x);
 	return 0;
 }

test2 containing the function declaration:

 #include <stdio.h>
 #include <stdlib.h>
 double foo(char x[])
 {
 	return atof(x);
 }

Compiling them both:

 gcc test1.c test2.c -o test.exe

results in a no errors/no warning at compilation time. But when test.exe runs, the value of the bar variable will be different from the expected 3.14000. The reason for that was explained above and in order to fix the unexpected behavior you will need to add the function prototype to the module (file) that contains the function call. So adding

 double foo(char x[]);

before the main will solve the issue.