Here are two files to be linked to create a single executable.
file1.c
/* file1.c */
#include <stdio.h>
int g; /* a global variable */
extern double dg; /* another global var, defined
in some other file */
void fctnOne(); /* a function prototype */
int main()
{
int x; /* a variable local to main
(an automatic variable) */
x = 3;
dg = 3.14;
g = 17;
fctnOne();
printf("x is %d, g is %d, dg is %f\n",
x, g, dg);
return 0;
}
void fctnTwo()
{
int x;
x = 5;
g = 11;
dg = dg * 2;
}
file2.c
/* file2.c */
extern int g;
double dg;
void fctnTwo(); /* function prototype */
void fctnOne()
{
int x = 44;
g = x;
dg = dg + 2;
fctnTwo();
}
The compiler command
gcc file1.c file2.c
would produce two object files, named file1.o and
file2.o. Each of these would have unresolved references,
that is, references to data and functions whose addresses are
not known, because they are in the other file.
Each object file would have two tables attached, a definition table which contains the address of all objects which are global, that is, could be referenced by a function in another file, and the usage table, which contains a list of all unresolved references. Here are the contents of the four tables.
| file1.o def | file1.use | file2.def | file2.use |
|---|---|---|---|
| g | dg line 13 | dg | g line 10 |
| main | fctnOne line 15 | fctnOne | fctnTwo line 12 |
| fctnTwo | printf line 16 | ||
| gd line 16 | |||
| gd line 17 | |||
| gd line 26 | |||
| gd line 26 |