Using Different Linkage Specifications (C++ Only)

C++ language only
When using the extern "literal" statement, consider that:
  • The string-literal parameter is case-insensitive. For example, extern "OS NOWIDEN", extern "OS nowiden", and extern "os NoWiden", although different in case are all handled in the same way.
  • The name of the function must follow the naming conventions of the other language. For example, for OS linkage specifications, the program name and all IBM® i objects must be uppercase. See Renaming Programs and Procedures.
  • A type definition of a function can be declared to have linkage information. After the type definition is declared, it can be used to declare functions of a particular linkage. The type definition declaration must be enclosed by braces: {}.
  • A function cannot be assigned directly to a pointer to a function with a different linkage. A type cast may be used to make this assignment possible. Type casting helps you eliminate parameter mismatching problems without excess constraint. See Type Casting to Override a Function without Overriding Linkage.
  • Functions that take function pointers as parameters may not be overloaded based on the linkage of the function pointers, as shown in the following code sample:
    // Using the typedef declarations above
    void foo (OS);
    void foo (CPP);  // undefined behavior, foo already declared
  • Functions that are defined with non-C++ linkage specifications accept parameters using the appropriate convention for that linkage. You do not need to widen parameters, as show in the following code sample:
    extern "C" void foo (char);  // chars are widened in C
    // In another compilation unit we then have
    extern "C" void foo (char c) // this parameter is correctly widened
    {
        // implementation of foo (char);
    }
  • Attempting to define a function with either extern "OS", extern "OS nowiden", or extern "builtin" linkage results in undefined behavior, as shown in the following code sample:
    extern "OS" void FOOPGM (char);  // declaration: OK
    extern "OS" void FOOPGM (char c) // definition: undefined behavior
    {
        // implementation of FOOPGM
    }
  • The declaration of a function pointer is:
    extern "OS" {
      typedef void (*fp) (char);
    }
    fp FOO;
    Note: Function FOO() is declared to be a function pointer of type fp.
  • The widening rules for all the linkage specifications shown in Table 1 are:
    • Any data type that is smaller than int is widened to int
    • float is widened to double
    • Address and Data pointers are not widened
    • struct has the same structure and information as the struct parameter passed
  • Data objects can be declared inside the extern linkage declaration:
    extern "OS" {
         int a1;
    }
    extern "OS" int a2;
    Note: Variable a1 is defined while variable a2 is only declared.
  • Functions FOO1(), FOO2(), and FOO3() are all declared as OS linkage functions. Functions FOO1() and FOO2() are declared by using the declaration-list syntax. FOO3() is declared by using the simple declaration.
    extern "OS" {
        void FOO1 (char, char *);
        void FOO2 (int, int *);
    }
    extern "OS" int FOO3 (double, double *);
  • In C++ linkage specifications, function identifiers are mangled. In all other linkage specifications, all function identifiers are identical to the exported names unless changed by the #pragma map directive.
    Note: For the syntax and description, see the ILE C/C++ Compiler Reference.