revised: 01/06/2008, 06/23/2017
The scope of an identifier is concerned with what the compiler can see. For example, when the compiler converts the following into machine language,
sum = alpha + beta;
it needs to know which
variables sum
, alpha
and beta
refer to.
Several different entities in a single source file might use these names, and
scope is used to keep them neatly separated.
The output of the compiler is an object file. Each object file is
created from just one source file.
The linkage of an identifier is concerned with what the linker does with various entities (variables and functions) that have already been compiled and are now located in various object files. The linker creates an executable file out of several object files and library files.
An object file contains functions and external variables that are in a form that is close to machine language. These entities are identified by name so other parts of the program can use them. A library is a file that contains a collection of object files.
An entity in an object file uses the same identifier as its declaration
in a source file. For example, the function foo()
might be defined
in a source file. In the corresponding object file there will be a section
of machine language called foo
. Another source file might
try to call foo()
.
But how can it do this when foo()
exists in a different file?
This is done by the linker when it links the object files together.
One object file defines foo()
and keeps the name foo
with the definition.
The other object file contains the code that calls foo()
, wherever it is.
The linker connects the call with the definition.
When does the same identifier in several object files correspond to just one entity and when does it correspond to several different entities? The linkage of the identifiers resolves this. Study the following picture
The identifier x
is used in three different source files. The
source files are compiled into three object files. The object files are linked
into one executable file. Source files in a project need to refer to entities
defined in other source files. In the picture, fileA.c and fileC.c
both refer to a single entity x
. The x
in fileB.c
is a local variable and is a different entity.
Object files contain information about their entities, including their identifiers.
When an entity (such as a variable) is external, the linker ensures
that there is only one of that entity in the executable file. In the picture,
variable x
in fileA.c and fileC.c is external.
Even though two object files refer to it, the linker ensures that there is
just one x
in the executable.
The picture shows the executable with a single int
variable
x
(as a little box of memory) and the functions foo()
and main()
all linked together. The executable file does not
contain the names of entities, although they are shown in the picture. An
executable file is nearly pure machine code and data, although usually some
debugging information is also included.