views:

135

answers:

1

As the question states, what exactly are the implications of having the 'implicit declaration of function' warning? We just cranked up the warning flags on gcc and found quite a few instances of these warnings and I'm curious what type of problems this may have caused prior to fixing them?

Also, why is this a warning and not an error. How is gcc even able to successfully link this executable? As you can see in the example below, the executable functions as expected.

Take the following two files for example:

file1.c

#include <stdio.h>

int main(void)
{
   funcA();
   return 0;
}

file2.c

#include <stdio.h>

void funcA(void)
{
   puts("hello world");
}

Compile & Output

$ gcc -Wall -Wextra -c file1.c file2.c
file1.c: In function 'main':
file1.c:3: warning: implicit declaration of function 'funcA'

$ gcc -Wall -Wextra file1.o file2.o -o test.exe
$ ./test.exe
hello world
+6  A: 

If the function has a definition that matches the implicit declaration (ie. it returns int and has a fixed number of arguments, and does not have a prototype), and you always call it with the correct number and types of arguments, then there are no negative implications (other than bad, obsolete style).

ie, in your code above, it is as if the function was declared as:

int funcA();

Since this doesn't match the function definition, the call to funcA() from file1.c invokes undefined behaviour, which means that it can crash. On your architecture, with your current compiler, it obviously doesn't - but architectures and compilers change.

GCC is able to link it because the symbol representing the function entry point doesn't change when the function type changes (again... on your current architecture, with your current compiler - although this is quite common).

Properly declaring your functions is a good thing - if for no other reason than that it allows you to give your function a prototype, which means that the compiler must diagnose it if you are calling it with the wrong number or types of arguments.

caf
A little elucidation. When in doubt (i.e. undefined) the compiler assumes the return type of a function to be **int** This is the default behaviour of several C-compilers. Hence the assumption int funcA( );
CVS-2600Hertz
@caf: Very interesting. So lets say that 'funcA' had a prototype of `char* funcA(void);` so that it returned a pointer to a string and I used the return value in a `strcpy`. With an implicit declaration would that be equivalent to doing `strcpy(buff, (int)funcA())`? I realize that undefined behavior is just that, but I'm still curious what my implementation is actually doing (Linux + gcc).
SiegeX
@CVS: thanks for the new vocab word, I'll have to remember that one!
SiegeX
SiegeX: That depends entirely on your architecture ABI, and how function return values are handled. On x86, both pointer and int return value are passed in the `%eax` register, so it will be equivalent. Note that on x86_64, because `char *` and `int` have different sizes it will truncate the pointer value.
caf
CVS: The type of the implicit declaration is actually part of the C language spec, it isn't just the default of some compilers.
caf