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
}