As you know, you may not declare functions in C before using them. That's because (in the c89 standard) if your function was not declared before it's being used (i.e. called), the function is assumed to be declared as:

extern int func();

where func is actually your function name. So this way the compiler assumes the your function retuns an int and can take any number of parameters without checking their types (ouch!). You can read the full text in the section Function calls of the standard. The c99 and c11 standards have removed this feature, but, by default, the compiler only issues a warning (as you will se below).

Suppose we have this very simple example:

The declaration of the func function in the func.h file:

#ifndef FUNC_H_
#define FUNC_H_

int func(char *s, int i);

#endif /* FUNC_H_ */

and it's definition in the func.c file:

#include <stdio.h>
#include "func.h"

int func(char *s, int i)
        return printf("Params given s: %s, i: %d\n", s, i);

and we have this file from which the func is called:

#include <stdio.h>

int main(int argc, char *argv[])
        int ret;

        printf("Before calling func\n");
        ret = func(argc);
        printf("func returned %d\n", ret);

        return 0;

You may have noticed that the func.h header is not included, there's only one parameter passed instead of two and with a different (non-compatible type). So what does happen when we compile and run this code?

Compiling this code with gcc and clang with default options gives us the warning implicit declaration of function ‘func’ (or implicit declaration of function 'func' is invalid in C99 for clang) and that is because both gcc and clang use by default the gnu99 standard (c99 + gnu extensions). Compiling with -std=c89 option does not give this warning because this is an allowed feature by the standard. The -pedantic-errors with a standard different than c89 (i.e. c99 or c11) will make both compiler behave as per standard: emit an error and abort.

After compiling the code (without -pedantic-errors), this is the output of the program (on my Linux machine, the executable is named test):

Before calling func
[1]    15901 segmentation fault (core dumped)  ./test

It crashed and it's obvious why. That being said, always declare your functions in header files and include them in the source files to prevent programming errors caused by this behaviour.