Lesson 9 | Linkage rules |
Objective | Rules for resolving external references |
Linking Separate C++ Modules
Examine the rules for resolving external references when linking separate modules. Modern systems are built around multifile inclusion, compilation, and linkage.
For C++, it is necessary to understand how multifile programs are combined. Conceptually, files are individual modules of a larger program. Linking separate modules requires resolving external references.
The key rule is that external nonstatic variables must be defined in only one place.
Use of the keyword extern
, together with an initializer, constitutes defining a variable. Using the keyword extern
without an initializer constitutes a declaration but is not a definition.
If the keyword extern
is omitted, the resulting declaration is a definition, with or without an initializer.
Example
Consider these declarations in four files that would be linked:
In file prog1.cpp: |
char c; //definition of c
.....
|
In file prog2.cpp:
|
extern char c; //declaration of c
.....
|
In file prog3.cpp:
|
extern int n = 5; //definition of n
.....
|
In file prog4.cpp:
|
char c; //illegal --
//second definition
extern float n; //illegal --
//type mismatch
extern int k; //illegal --
//no definition
.....
|
Namespaces
The purpose of namespaces is to localize the names of identifiers to avoid name collisions. The C++ programming environment has seen an explosion of variable, function, and class names. Prior to the invention of namespaces,
all of these names competed for slots in the global namespace and many conflicts arose.
For example, if your program defined a function called abs( ), it could (depending upon its parameter list) override the standard library function abs( ) because both names would be stored in the global namespace.
Name collisions were compounded when two or more third-party libraries were used by the same program. In this case, it was possible that a name defined by one library would conflict with the same name defined by the other library.
The situation can be particularly troublesome for class names. For example, if your program defines a class call ThreeDCircle and a library used by your program defines a class by the same name, a conflict will arise.
Creation of namespace keyword
The creation of the namespace keyword was a response to these problems. Because it localizes the visibility of names declared within it, a namespace allows the same name to be used in different contexts without conflicts arising.
Perhaps the most noticeable beneficiary of namespace is the C++ standard library. Prior to namespace, the entire C++ library was defined within the global namespace (which was, of course, the only namespace).
Since the addition of namespace, the C++ library is now defined within its own namespace, called std, which reduces the chance of name collisions. You can also create your own namespaces within your program to localize the visibility of any
names that you think may cause conflicts. This is especially important if you are creating class or function libraries.