There are 3 scenarios, you describe:
- with 2
.cfiles and withint i;in the header. - With 2
.cfiles and withint i=100;in the header (or any other value; that doesn’t matter). - With 1
.cfile and withint i=100;in the header.
In each scenario, imagine the contents of the header file inserted into the .c file and this .c file compiled into a .o file 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
- to put either
extern int i;or justint i;into the header file, - and then to put the “real” definition of i (namely
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.)