The extern storage class specifier

A function that is declared with the extern storage class specifier has external linkage, which means that it can be called from other translation units. The keyword extern is optional; if you do not specify a storage class specifier, the function is assumed to have external linkage.

C++ only. An extern declaration cannot appear in class scope. You can use the extern keyword with arguments that specify the type of linkage.

Read syntax diagramSkip visual syntax diagram
extern function storage class specifier syntax

>>-extern--"--linkage_specification--"-------------------------><

where linkage_specification can be any of the following:
  • builtin
  • C
  • C++
  • COBOL
  • FORTRAN
  • OS
  • OS_DOWNSTACK
  • OS_NOSTACK
  • OS_UPSTACK
  • PLI
For an explanation of these options, see the descriptions in #pragma linkage (C only).
The following fragments illustrate the use of extern "C" :
extern "C" int cf();      //declare function cf to have C linkage

extern "C" int (*c_fp)(); //declare a pointer to a function,
                          // called c_fp, which has C linkage

extern "C" {
  typedef void(*cfp_T)(); //create a type pointer to function with C
                          // linkage
  void cfn();             //create a function with C linkage
  void (*cfp)();          //create a pointer to a function, with C
                          // linkage
}
Linkage compatibility affects all C library functions that accept a user function pointer as a parameter, such as qsort. Use the extern "C" linkage specification to ensure that the declared linkages are the same. The following example fragment uses extern "C" with qsort.
#include <stdlib.h>

// function to compare table elements
extern "C" int TableCmp(const void *, const void *); // C linkage
extern void * GenTable();                            // C++ linkage

int main() {
  void *table;

  table = GenTable();               // generate table
  qsort(table, 100, 15, TableCmp);  // sort table, using TableCmp
                                    // and C library routine qsort();
}
While the C++ language supports overloading, other languages do not. The implications of this are:
  • You can overload a function as long as it has C++ (default) linkage. Therefore, z/OS® XL C++ allows the following series of statements:
    int func(int);             // function with C++ linkage
    int func(char);            // overloaded function with C++ linkage
    By contrast, you cannot overload a function that has non-C++ linkage:
    extern "FORTRAN"{int func(int);}
    extern "FORTRAN"{int func(int,int);}  // not allowed
                                          //compiler will issue an error message
  • Only one non-C++-linkage function can have the same name as overloaded functions. For example:
    int func(char); 
    int func(int); 
    extern "FORTRAN"{int func(int,int);}
    However, the non-C++-linkage function cannot have the same parameters as any of the C++ functions with the same name:
    int func(char);      // first function with C++ linkage
    int func(int, int);  // second function with C++ linkage
    extern "FORTRAN"{int func(int,int);}  // not allowed since the parameter 
                                          // list is the same as the one for
                                          // the second function with C++ linkage
                                          // compiler will issue an error message
End C++ only