I have a 2 modules (.c files) and one .h header file:
file1.c:
#include <stdio.h>
#include "global.h"
int main()
{
i = 100;
printf("%d\n",i);
foo();
return 0;
}
file2.c
#include <stdio.h>
#include "global.h"
void foo()
{
i = 10;
printf("%d\n",i);
}
global.h
int i;
extern void foo()
When I do gcc file1.c file2.c everything works fine and I get the expected output. Now, when I initialize variable ‘i’ in the header file to say 0 and compile again I get a linker error:
/tmp/cc0oj7yA.o:(.bss+0x0): multiple definition of `i'
/tmp/cckd7TTI.o:(.bss+0x0): first defined here
If I just compile file1.c (removing call to foo()) with the initialization in the header file i.e. gcc file1.c, everything works fine. What is going on?
There are 3 scenarios, you describe:
.cfiles and withint i;in the header..cfiles and withint i=100;in the header (or any other value; that doesn’t matter)..cfile and withint i=100;in the header.In each scenario, imagine the contents of the header file inserted into the
.cfile and this.cfile compiled into a.ofile and then these linked together.Then following happens:
works fine because of the already mentioned “tentative definitions”: every
.ofile contains one of them, so the linker says “ok”.doesn’t work, because both
.ofiles contain a definition with a value, which collide (even if they have the same value) – there may be only one with any given name in all.ofiles which are linked together at a given time.works of course, because you have only one
.ofile and so no possibility for collision.IMHO a clean thing would be
extern int i;or justint i;into the header file,int i = 100;) intofile1.c. In this case, this initialization gets used at the start of the program and the corresponding line inmain()can be omitted. (Besides, I hope the naming is only an example; please don’t name any global variables asiin real programs.)