From RAD Studio
Jump to: navigation, search

Go Up to Declarations Index

An executable program is usually created by compiling several independent translation units, then linking the resulting object files with preexisting libraries. A problem arises when the same identifier is declared in different scopes (for example, in different files), or declared more than once in the same scope. Linkage is the process that allows each instance of an identifier to be associated correctly with one particular object or function. All identifiers have one of three linkage attributes, closely related to their scope: external linkage, internal linkage, or no linkage. These attributes are determined by the placement and format of your declarations, together with the explicit (or implicit by default) use of the storage class specifier static or extern.

Each instance of a particular identifier with external linkage represents the same object or function throughout the entire set of files and libraries making up the program. Each instance of a particular identifier with internal linkage represents the same object or function within one file only. Identifiers with no linkage represent unique entities.

External and internal linkage rules

Any object or file identifier having file scope will have internal linkage if its declaration contains the storage class specifier static.

For C++, if the same identifier appears with both internal and external linkage within the same file, the identifier will have external linkage. In C, it will have internal linkage.

If the declaration of an object or function identifier contains the storage class specifier extern, the identifier has the same linkage as any visible declaration of the identifier with file scope. If there is no such visible declaration, the identifier has external linkage.

If a function is declared without a storage class specifier, its linkage is determined as if the storage class specifier extern had been used.

If an object identifier with file scope is declared without a storage class specifier, the identifier has external linkage.

Identifiers with no linkage attribute:

  • Any identifier declared to be other than an object or a function (for example, a typedef identifier)
  • Function parameters
  • Block scope identifiers for objects declared without the storage class specifier extern

Name mangling

When a C++ module is compiled, the compiler generates function names that include an encoding of the function's argument types. This is known as name mangling. It makes overloaded functions possible, and helps the linker catch errors in calls to functions in other modules. However, there are times when you won't want name mangling. When compiling a C++ module to be linked with a module that does not have mangled names, the C++ compiler has to be told not to mangle the names of the functions from the other module. This situation typically arises when linking with libraries or .obj files compiled with a C compiler

To tell the C++ compiler not to mangle the name of a function, declare the function as extern "C", like this:

extern "C" void Cfunc( int );

This declaration tells the compiler not to mangle references to the function Cfunc.

You can also apply the extern "C" declaration to a block of names:

extern "C" {
   void Cfunc1( int );
   void Cfunc2( int );
   void Cfunc3( int );

As with the declaration for a single function, this declaration tells the compiler that references to the functions Cfunc1, Cfunc2, and Cfunc3 should not be mangled. You can also use this form of block declaration when the block of function names is contained in a header file:

extern "C" {
   #include "locallib.h"

Note: extern "C" cannot be used with class identifiers.

See Also