2

I strangely found that C allows linking of function where argument list doesn't match:

//add.c
int add(int a, int b, int c) {
    return a + b + c;
}
//file.c
int add (int,int); //Note: only 2 arguments
void foo() {
    add(1,2);
}

I compiled add.c first, then compiled file.c, both got compiled successfully. Strangely, linker didn't give any sort of error or warning, probably the reason is C linker doesn't compare arguments while linking. I'm not 100% sure about it though. Someone please comment on this.

Now, the question is what is the good practice to avoid this situation or get some sort of warning during compilation, because in my project there are lot of functions in different files, and now & then we have to add some extra argument in the function.

Vivek Agrawal
  • 113
  • 11
  • function will operate as-if it had all the parameter, but the third parameter could just be junk and leads to [UB](http://en.wikipedia.org/wiki/Undefined_behavior). – Dayal rai May 20 '15 at 09:55
  • 1
    @Dayalrai: no - it's undefined behaviour - almost anything can happen. On many ABIs the stack frame will be incorrect, leading to potentially disastrous consequences. – Paul R May 20 '15 at 09:57
  • You have a double -and inconsistent- declaration. Declarations are only useful at compile time, so the compiler can check that the function is used correctly. If you manage to fool the compiler like you have done, the linker will just find a call to `add()` and code for `add()` and will link them together. – deStrangis May 20 '15 at 09:57
  • The correct behaviour is to have an include file that exposes the prototypes (function declarations) that are in a C file. If you have add.c you must have add.h where the functions of add.c are declared as prototypes ... This behaviour allows you to avoid the issue you indicate. You may use `gcc -Wall` to verify all warnings, the option `--pedantic` indicates more warning (but is very boring) – Sir Jo Black May 20 '15 at 09:59
  • Can somebody tell me, why did I get downvote? At least I deserve a reason for the downvote. – Vivek Agrawal May 20 '15 at 10:00
  • 1
    I don't want to get into a vote war but upvoted because this is a perfectly reasonable question that will lead an improved understanding of 'C'. – Persixty May 20 '15 at 10:21

3 Answers3

7

Use your header files correctly.
Configure your compiler to emit as many warnings as possible.
Mind the warnings!

add.h

#ifndef ADD_H_INCLUDED
#define ADD_H_INCLUDED
int add(int a, int b, int c);
#endif

add.c

#include "add.h"
int add(int a, int b, int c) {
    return a + b + c;
}

file.c

#include "add.h"
void foo() {
    add(1, 2);
}
pmg
  • 106,608
  • 13
  • 126
  • 198
5

Calling a function with to few arguments leads to undefined behavior as the value of those arguments will be indeterminate.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
5

C linker doesn't compare arguments while linking.

That is correct. Unlike C++ linker which considers argument types to be part of a function signature, C linker considers only function names. That is why it is possible to create a situation with undefined behavior simply by supplying a wrong function prototype the way that you show.

what is the good practice to avoid this situation or get some sort of warning during compilation?

Always put prototypes of functions that you are intended to share into a header, and include that header from the places where the function is used and the place where the function is defined. This would ensure that compiler issues a diagnostic message. Treat all compiler warnings as errors. C compilers are often rather forgiving, so their warnings usually indicate something very important.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523