Reputation: 105
actually I was compiling with multiple files. Following are the files:
file main.c -->
#include <stdio.h>
void foo3(void)
{
printf("INSIDE foo3 function\n");
}
int main()
{
foo1();
foo2();
foo3();
}
file 1.c -->
#include <stdio.h>
void foo1(void)
{
printf("INSIDE foo1 function\n");
}
file 2.c-->
#include <stdio.h>
void foo2(void)
{
printf("INSIDE foo2 function\n");
}
Now I compiled using gcc as follows-->
gcc 1.c 2.c main.c -o main
following was the output -->
INSIDE foo1 function
INSIDE foo2 function
INSIDE foo3 function
My doubt is how could main
() call foo1()
and foo2()
when they are not declared in main.c
. But now if I change main.c as follows ( writing the definition of foo3()
after main()
) like this:
edited main.c -->
#include <stdio.h>
int main()
{
foo1();
foo2();
foo3();
}
void foo3(void)
{
printf("INSIDE foo3 function\n");
}
and then if I compile I get this error:
main.c:9:6: warning: conflicting types for ‘foo3’ [enabled by default]
void foo3(void)
^
main.c:6:2: note: previous implicit declaration of ‘foo3’ was here
foo3();
^
why was this error not shown earlier in case of foo1()
and foo2()
. Thankyou in advance.
Upvotes: 0
Views: 406
Reputation: 1
My doubt is how could
main()
callfoo1()
andfoo2()
when they are not declared inmain.c
Because the GCC compiler defaults to the old ANSI C (aka as C89) language, where undeclared functions are permitted and defaults to giving int
result.
Try to invoke the compiler as e.g.
gcc -std=c99 -Wall -g -c main.c
or (if you want to compile all files at once)
gcc -std=c99 -Wall -g 1.c 2.c main.c -o main
You could ask for link time interprocedural optimizations with gcc -flto
instead of gcc
using a recent GCC, e.g. GCC 4.9 in september 2014.
This would want a C99 conforming source code where all functions should be declared.
The -Wall
asks for (almost) all warnings. The -g
option produces a debuggable object code (or executable for the last command compiling all files at once).
In your edited main.c
when foo3
first occurrence (inside main
) is encountered, the compiler guesses that it is a function returning int
. When the compiler sees the definition of foo3
it rightly complains.
You could use the -Wstrict-prototypes
warning option to gcc
(but it is implied by -Wall
which I always recommend using).
At link time, the type (and signature) of C functions does not matter. The linker just uses name to do its job (but C++ use name mangling). Of course, calling a function with the incorrect arguments or result is undefined behavior.
The good conventional practice is to have a common header file declaring all the used and public functions and types (and constants) and include that header file in your source files (this avoids to have to copy and paste these declarations several times). So you whould have a new header file myheader.h
like
// file myheader.h
#ifndef MY_HEADER_INCLUDED
#define MY_HEADER_INCLUDED
void foo1(void);
void foo2(void);
void foo3(void);
#endif /*MY_HEADER_INCLUDED*/
and you would add #include "myheader.h"
in all your source files (after the #include <stdio.h>
directive there). Notice the include guard trick with MY_HEADER_INCLUDED
.
In practice, header files usually contain comments explaining the API of your program.
Learn also about GNU make. It will ease the building of your multi-source code files programs (you just compile and build by running make
). See this and that examples of Makefile
. Understand that C preprocessing is the first phase of C compilation.
Upvotes: 1