Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function prototype in header file doesn't match definition, how to catch this?

(I found this question which is similar but not a duplicate: How to check validity of header file in C programming language )

I have a function implementation, and a non-matching prototype (same name, different types) which is in a header file. The header file is included by a C file that uses the function, but is not included in the file that defines the function.

Here is a minimal test case :

header.h:

void foo(int bar);

File1.c:

#include "header.h"
int main (int argc, char * argv[])
{
    int x = 1;
    foo(x);
    return 0;
}

File 2.c:

#include <stdio.h>

typedef struct {
    int x;
    int y;
} t_struct;

void foo (t_struct *p_bar)
{
    printf("%x %x\n", p_bar->x, p_bar->y);
}

I can compile this with VS 2010 with no errors or warnings, but unsurprisingly it segfaults when I run it.

  • The compiler is fine with it (this I understand)
  • The linker did not catch it (this I was slightly surprised by)
  • The static analysis tool (Coverity) did not catch it (this I was very surprised by).

How can I catch these kinds of errors?

[Edit: I realise if I #include "header.h" in file2.c as well, the compiler will complain. But I have an enormous code base and it is not always possible or appropriate to guarantee that all headers where a function is prototyped are included in the implementation files.]

like image 555
Vicky Avatar asked Feb 28 '13 14:02

Vicky


People also ask

What will happen if the function definition does not match the function declaration?

The compiler will then reject the definition of base() since it doesn't match the preceding declaration.

What happens if one of the argument names in a function declaration does not match that of the corresponding function definition?

It is an error if the number of arguments in a function definition, declaration, or call does not match the prototype. If the data type of an argument in a function call does not match the corresponding type in the function prototype, the compiler tries to perform conversions.

Which prototype of the function is used in the header file?

The function prototype is also called the function declaration (as opposed to the function definition, which includes the body of the function). You can also put function prototypes in header files, whose names end with . h, and then include them with stdio.

Can you put function definitions in a header file?

Because a header file might potentially be included by multiple files, it cannot contain definitions that might produce multiple definitions of the same name. The following are not allowed, or are considered very bad practice: built-in type definitions at namespace or global scope. non-inline function definitions.


2 Answers

Have the same header file included in both file1.c and file2.c. This will pretty much prevent a conflicting prototype.

Otherwise, such a mistake cannot be detected by the compiler because the source code of the function is not visible to the compiler when it compiles file1.c. Rather, it can only trust the signature that has been given.

At least theoretically, the linker could be able to detect such a mismatch if additional metadata is stored in the object files, but I am not aware if this is practically possible.

like image 118
Blagovest Buyukliev Avatar answered Nov 15 '22 19:11

Blagovest Buyukliev


-Werror-implicit-function-declaration, -Wmissing-prototypes or equivalent on one of your supported compilers. then it will either error or complain if the declaration does not precede the definition of a global.

Compiling the programs in some form of strict C99 mode should also generate these messages. GCC, ICC, and Clang all support this feature (not sure about MS's C compiler and its current status, as VS 2005 or 2008 was the latest I've used for C).

like image 22
justin Avatar answered Nov 15 '22 20:11

justin