0

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.

Akhil
  • 105
  • 1
  • 8

1 Answers1

1

My doubt is how could main() call foo1() and foo2() when they are not declared in main.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.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • thankyou for the valuable information. one more doubt. why is it not showing conflicting type warning for foo2() and foo1(), when they are also appearing for the first time in main() like foo3() without any previous declaration in main.c. – Akhil Sep 02 '14 at 07:46
  • You need link time optimizations for that. But what is important for you is to take the habit of writing and using your header files and declare all the public things there. – Basile Starynkevitch Sep 02 '14 at 07:56
  • oh okay. main.c compilation will only show the warning of foo3.c since it is only function defined within main.c. So, the above warning for foo3() is the only warning in main.c, other functions are assumed to return int type during the compilation of main.c and hence no warning occurs for them since their definition does not occur while compilation of main.c. Thank you for you valuable support. – Akhil Sep 02 '14 at 08:53