1

I'm a beginner into Linking, lets say I have two .c files

file1.c is

#include <stdio.h>
#include "file2.c"


int main(int argc, char *argv[]) 
{
    int a = function2();
    printf("%d",a);
    return 0;
}

and file2.c is

int function2() 
{ 
    return 2018;
}

when I compiled, there is a linker error which is multiple definition of function2, but I only define function once in file2.c?

  • 3
    `#include "file2.c"` is a whole wrong approach, – Sourav Ghosh Nov 01 '18 at 14:17
  • 1
    Function *definitions* (implementation) in source files. Function *declarations* in header files. Include header files, build with source files. – Some programmer dude Nov 01 '18 at 14:20
  • 1
    If you `#include "file2.c"` you don't need to compile `file2.c` separately and link it with `file1.o` — the information in `file2.o` is already in `file1.o`. What's more normal is to `#include "file2.h"` in both `file2.c` and `file1.c`, and then you need to compile and link both source files into one executable. – Jonathan Leffler Nov 01 '18 at 14:23

3 Answers3

2

You should create a header file, "file2.h", with:

int function2(void);

and a file "file2.c" with the function: "file2.h" with:

#include "file2.h"

int function2(void) 
{ 
    return 2018;
    ...
} 

Then in your main you have to include the header with:

#include "file2.h"

Keep care that all those files should be in the same folder to avoid any link problem

MaDryn
  • 31
  • 7
2

Try something like this:

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

int main(int argc, char *argv[]) 
{
    int a = function2();
    printf("%d",a);
    return 0;
}

file2.h:

extern int function2(void);

and file2.c is

#include "file2.h"

int function2(void) 
{ 
    return 2018;
}

And then link it together.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Mike
  • 4,041
  • 6
  • 20
  • 37
  • My personal opinion: You should remove the `extern` from `file2.h`, it's not wrong, but not necessary – Jabberwocky Nov 01 '18 at 14:27
  • 1
    @Jabberwocky: not everyone would agree with you — for instance, I don't. – Jonathan Leffler Nov 01 '18 at 14:28
  • @JonathanLeffler could you please elaborate? – Jabberwocky Nov 01 '18 at 14:28
  • @Jabberwocky: I prefer to see `extern int function2(void)l;` in the header. I accept that there are people who prefer not to see `extern`; I prefer to see `extern`, if only for symmetry with the `extern` declaration of those global variables that sometimes have to be declared in headers, where the `extern` is crucial. – Jonathan Leffler Nov 01 '18 at 14:29
  • @JonathanLeffler OK, but we agree the `extern` keyword on function declarations is purely decorative, it doesn't change anything, does it? – Jabberwocky Nov 01 '18 at 14:30
  • 2
    @Jabberwocky: Attached to a function declaration, the keyword `extern` is optional — yes. It is, IMO, clearer when present, but not everyone agrees with me (any more than everyone agrees with you). – Jonathan Leffler Nov 01 '18 at 14:31
0

The statement #include "file2.c" effectively incorporates the contents of file2.c into file1.c. Then file1.c is compiled as if it contains:

int function2() 
{ 
    return 2018;
}

Those lines define function2; they tell the compiler “Here is function2, create code for it.” Because those lines effectively appear in both file1.c and file2.c, your program has two copies of function2.

Instead, you should create file2.h that contains:

int function2();

That line tells the compiler “There exists a function called function2, but its definition is somewhere else.”

Then, in file1.c, use #include "file2.h" instead of #include "file2.c". This will tell the compiler, while file1.c is being compiled, what it needs to know to compile a call to function2. The compiler will have the declaration it needs, but it will not have the definition, which is not needed in file1.c.

Also, in file2.c, insert #include "file2.h". Then file2.c will contain both a declaration of function2 (from file2.h) and a definition of function2 (from the actual lines in file2.c). The purpose of this is so the compiler can see both the declaration and the definition while it is compiling file2.c, so it can warn you if there is a typographical error that makes them incompatible.

Additionally, in C, you should use int function2(void) rather than int function2(). For historic reasons, the latter leaves the parameters unspecified. Using (void) tells the compiler there are no parameters.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Hi Thanks for your answer. but if I don't insert #include "file2.h". into file2.c, it is still OK to complier, so why I need to insert #include "file2.h" since #include "file2.h" already in file1.c? –  Nov 01 '18 at 23:28
  • @amjad: The purpose of this is so the compiler can see both the declaration and the definition while it is compiling `file2.c`, so it can warn you if there is a typographical error that makes them incompatible. – Eric Postpischil Nov 01 '18 at 23:37
  • hi, could you give me an example of typographical error that makes them incompatible, please? thank you so much –  Nov 02 '18 at 00:08
  • 1
    `file2.h` could say `int foo(void);`, while `file2.c` says `float foo(void) …`. – Eric Postpischil Nov 02 '18 at 00:15