The __cdecl function specifier (C++ only)

You can use the __cdecl keyword to set linkage conventions for function calls in C++ applications. The __cdecl keyword instructs the compiler to read and write a parameter list by using C linkage conventions.

To set the __cdecl calling convention for a function, place the linkage keyword immediately before the function name or at the beginning of the declarator. For example:
void __cdecl f();
char (__cdecl *fp) (void);
z/OS® XL C++ allows the __cdecl keyword on member functions and nonmember functions. These functions can be static or nonstatic. It also allows the keyword on pointer-to-member function types and the typedef specifier.
Note: The compiler accepts both _cdecl and __cdecl (both single and double underscore).
Following is an example:
// C++ nonmember functions
void __cdecl f1();
static void __cdecl f2();

// pointer to member function type
char (__cdecl *A::mfp) (void);

// typedef
typedef  void (* _cdecl void_fcn)(int);
// C++ member functions
class A {
  public:
    void __cdecl func();
    static void __cdecl func1();
}

// Template member functions
template <class T> X {
  public:
    void __cdecl func();
    static void __cdecl func1();
}

// Template functions
template <class T> T __cdecl foo(T i) {return i+1;}
template <class T> T static _cdecl foo2(T i) {return i+1;}

The __cdecl linkage keyword only affects parameter passing; it does not prevent function name mangling. Therefore, you can still overload functions with non-default linkage. Note that you only acquire linkage by explicitly using the __cdecl keyword. It overrides the linkage that it inherits from an extern "linkage" specification.

Following is an example:
void __cdecl foo(int);  // C linkage with name mangled
void __cdecl foo(char)  // overload foo() with char is OK

void foo(int(*)());
   // overload on linkage of function
void foo(int (__cdecl *)());
   //pointer parameter is OK
extern "C++" {
   void __cdecl foo(int);
   // foo() has C linkage with name mangled
}

extern "C" {
   void __cdecl foo(int);
   // foo() has C linkage with name mangled
}
If the function is redeclared, the linkage keyword must appear in the first declaration; otherwise an error message is issued. Following are two examples:
 int c_cf();
 int __cdecl c_cf();
 // Error 1251. The previous declaration did not have a linkage
 specification
 int __cdecl c_cf();
 int c_cf();
   // OK, the linkage is inherited from the first declaration

Example of __cdecl use

The following example illustrates how you can use __cdecl to pass in a C parameter list from C++ code to a C function:

/*------------------------------------------------------------------*/
/*  C++ source file                                                 */
/*------------------------------------------------------------------*/
//
//  C++ Application:  passing a C++ function pointer to a C function
//
#include <stdio.h>

// C++ function declared with C calling convention
 void __cdecl callcxx() {
   printf(" I am a C++ function\n");
 }

// declare a function pointer with __cdecl linkage
 void (__cdecl *p1)();

// declare an extern C function,
// accepting a__cdecl function pointer
 extern "C" {
   void CALLC(void (__cdecl *pp)());
 }

// assign the function pointer to a __cdecl function
 int main() {
   p1 =  callcxx;

// call the C function with the __cdecl function pointer
   CALLC(p1);
 }
/*-----------------------------------------------------------------*/
/*  C source file                                                  */
/*-----------------------------------------------------------------*/

/*                                                                 */
/*  C Routine:  receiving a function pointer with C linkage        */
/*                                                                 */
#include <stdio.h>
extern void CALLC(void (*pp)()){
   printf(" I am a C function\n");
   (*pp)();   // call the function passed in
 }