The term “linkage specification” refers to the protocol for linking functions (or procedures) written in different languages. The following calling conventions are affected:
Case sensitivity of names.
Decoration of names. In C, the compiler prefixes names with an underscore. This is often called “decoration.” In C++, name decoration is used to retain type information through the linkage phase. (For more information, see Appendix A, “Phases of Translation.”)
Order in which arguments are expected on the stack.
Responsibility for adjusting the stack on function return. Either the called function or the calling function is responsible.
Passing of hidden arguments (whether any hidden arguments are passed).
The calling conventions for Microsoft C and C++ are shown in Table 6.3.
Table 6.3 C and C++ Calling Conventions
Calling Convention | C++ | C |
Case sensitivity | Case sensitive | Case sensitive |
Order of arguments | Left argument pushed first; this passed last (class-member functions only) | Right argument pushed first |
Stack responsibility | Called function | Calling function |
Hidden arguments | For member functions, the this pointer is passed as a hidden argument | Used only for structure and floating return types |
Naming | C++ type-safe naming | C naming; all names prefixed with an underscore (_)¨ |
linkage-specification:
extern string-literal { declaration-listopt }
extern string-literal declaration
declaration-list:
declaration
declaration-list
Linkage specification facilitates gradually porting C code to C++ by allowing the use of existing code.
The only linkage specifications currently supported by Microsoft C++ are "C" and "C++". ¨
The following example declares the functions atoi and atol with C linkage:
extern “C”
{
int atoi( char *string );
long atol( char *string );
}
Calls to these functions are made using C linkage. The same result could be achieved with these two declarations:
extern “C” int atoi( char *string );
extern “C” long atol( char *string );
All Microsoft C standard include files use conditional compilation directives to detect C++ compilation. When a C++ compilation is detected, the prototypes are enclosed in an extern “C” directive as follows:
// Sample.h
#if defined(__cplusplus)
extern “C”
{
#endif
// Function declarations
#if defined(__cplusplus)
}
#endif¨
There is no need for you to declare the functions in the standard include files as extern "C".
If a function is overloaded, no more than one of the functions of the same name can have a linkage specifier. (For more information, see “Function Overloading” in Chapter 7, on topic .)
Table 6.4 shows how various linkage specifications work.
Table 6.4 Effects of Linkage Specifications
Specification | Effect |
On an object | Affects linkage of that object only |
On a function | Affects linkage of that function and all functions or objects declared within it |
On a class | Affects linkage of all nonmember functions and objects declared within the class |
If a function has more than one linkage specification, they must agree; it is an error to declare functions as having both C and C++ linkage. Furthermore, if two declarations for a function occur in a program–one with a linkage specification and one without–the declaration with the linkage specification must be first. Any redundant declarations of functions that already have linkage specification are given the linkage specified in the first declaration. For example:
extern “C” int CFunc1();
...
int CFunc1(); // Redeclaration is benign; C linkage is
// retained.
int CFunc2();
...
extern “C” int CFunc2(); // Error: not the first declaration of
// CFunc2; cannot contain linkage
// specifier.
Functions and objects explicitly declared as static within the body of a compound linkage specifier ({ }) are treated as static functions or objects; the linkage specifier is ignored. Other functions and objects behave as if declared using the extern keyword. (See “Storage-Class Specifiers” for details about the extern keyword.)