I want to understand the external linkage and internal linkage and their difference.
I also want to know the meaning of
const
va
I think Internal and External Linkage in C++ gives a clear and concise explanation:
A translation unit refers to an implementation (.c/.cpp) file and all header (.h/.hpp) files it includes. If an object or function inside such a translation unit has internal linkage, then that specific symbol is only visible to the linker within that translation unit. If an object or function has external linkage, the linker can also see it when processing other translation units. The static keyword, when used in the global namespace, forces a symbol to have internal linkage. The extern keyword results in a symbol having external linkage.
The compiler defaults the linkage of symbols such that:
Non-const global variables have external linkage by default
Const global variables have internal linkage by default
Functions have external linkage by default
Before talking about the question, it is better to know the term translation unit, program and some basic concepts of C++ (actually linkage is one of them in general) precisely. You will also have to know what is a scope.
I will emphasize some key points, esp. those missing in previous answers.
Linkage is a property of a name, which is introduced by a declaration. Different names can denote same entity (typically, an object or a function). So talking about linkage of an entity is usually nonsense, unless you are sure that the entity will only be referred by the unique name from some specific declarations (usually one declaration, though).
Note an object is an entity, but a variable is not. While talking about the linkage of a variable, actually the name of the denoted entity (which is introduced by a specific declaration) is concerned. The linkage of the name is in one of the three: no linkage, internal linkage or external linkage.
Different translation units can share the same declaration by header/source file (yes, it is the standard's wording) inclusion. So you may refer the same name in different translation units. If the name declared has external linkage, the identity of the entity referred by the name is also shared. If the name declared has internal linkage, the same name in different translation units denotes different entities, but you can refer the entity in different scopes of the same translation unit. If the name has no linkage, you simply cannot refer the entity from other scopes.
(Oops... I found what I have typed was somewhat just repeating the standard wording ...)
There are also some other confusing points which are not covered by the language specification.
__attribute__
or __declspec
) or compiler options, and the image is not the whole program or the object file translated from a translation unit, thus no standard concept can describe it accurately. Since symbol is not a normative term in C++, it is only an implementation detail, even though the related extensions of dialects may have been widely adopted.The linkage rule of namespace scope const variable is something special (and particularly different to the const
object declared in file scope in C language which also has the concept of linkage of identifiers). Since ODR is enforced by C++, it is important to keep no more than one definition of the same variable or function occurred in the whole program except for inline functions. If there is no such special rule of const
, a simplest declaration of const
variable with initializers (e.g. = xxx
) in a header or a source file (often a "header file") included by multiple translation units (or included by one translation unit more than once, though rarely) in a program will violate ODR, which makes to use const
variable as replacement of some object-like macros impossible.
extern
declaration in the other file.static
. Such variables are said to have internal linkage.Consider following example:
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
f
declares f
as a function with external linkage (default). Its definition must be provided later in this file or in other translation unit (given below).max
is defined as an integer constant. The default linkage for constants is internal. Its linkage is changed to external with the keyword extern
. So now max
can be accessed in other files. n
is defined as an integer variable. The default linkage for variables defined outside function bodies is external.#include <iostream>
using namespace std;
extern const int max;
extern int n;
static float z = 0.0;
void f(int i)
{
static int nCall = 0;
int a;
//...
nCall++;
n++;
//...
a = max * z;
//...
cout << "f() called " << nCall << " times." << endl;
}
max
is declared to have external linkage. A matching definition for max
(with external linkage) must appear in some file. (As in 1.cpp)n
is declared to have external linkage.z
is defined as a global variable with internal linkage.nCall
specifies nCall
to be a variable that retains its value across calls to function f()
. Unlike local variables with the default auto storage class, nCall
will be initialized only once at the start of the program and not once for each invocation of f()
. The storage class specifier static
affects the lifetime of the local variable and not its scope.NB: The keyword static
plays a double role. When used in the definitions of global variables, it specifies internal linkage. When used in the definitions of the local variables, it specifies that the lifetime of the variable is going to be the duration of the program instead of being the duration of the function.
Hope that helps!