//file1.c
#include <stdio.h>
void p(int a)
{
printf("%d\n",a);
}
//file2.c
extern void p(float x); // external declaration doesn't match definition
int main(){
float b;
b=3.333f;
p(b);
}
Here the external declaration is wrong in that it is different from the actual function definition. I compile and link the two files with:
gcc -Wconversion -Wall -std=c99 file1.c file2.c
No warning is raised. Is there any gcc compiler option that can help capture this mismatch during compiling/linking?
It is not possible for a compiler to observe, while compiling file2.c, that a declaration in it does not match a declaration in file1.c, because, while compiling file2.c, the compiler has no knowledge of the contents of file1.c.
Some linkers have features that can help with this. However, this is not a common practice for linking C objects. (Perhaps it should be.)
This sort of mismatch is generally handled by using header files. The overwhelming common practice is to include declarations from a header, not to manually enter them in other source files. To do this:
- Create file1.h and put
void p(int a);
in it.
- In file1.c, insert
#include "file1.h"
.
- In file2.c, insert
#include "file1.h"
and remove the declaration of p
.
The purpose of including file1.h in file1.c is so that the compiler will see both the declaration in file1.h and the definition in file1.c, and it will complain if they are incompatible.
Then, since file1.h is included in file2.c, we are assured the declaration seen while compiling file2.c is compatible with the definition in file1.c.
This code causes undefined behaviour because the function is called via a declaration which is not compatible with the function definition.
To help with this you can:
- use
-flto
which will perform prototype checks at link time
- use
-Wmissing-declarations
which will warn about file1
having a function with external linkage but no prototype
- adopt a habit of never manually writing an
extern
function declaration in a .c
file -- always include a .h
file which is also included by the .c
file containing the function definition (the previous option will warn about this).