Pointers to functions
Pointers to functions
A pointer to a function points to the address of the executable code of the function. You can use pointers to call functions and to pass functions as arguments to other functions. You cannot perform pointer arithmetic on pointers to functions.
For z/OS® XL C/C++, use the __cdecl keyword to declare a pointer to a function as a C linkage. For more information, refer to The __cdecl function specifier (C++ only).
The type of a pointer to a function is based on both the return type and parameter types of the function.
int *f(int a); /* function f returning an int* */
int (*g)(int a); /* pointer g to a function returning an int */
In the first declaration, f is interpreted as a function that takes an int as argument, and returns a pointer to an int. In the second declaration, g is interpreted as a pointer to a function that takes an int argument and that returns an int.
auto(*fp)()->int;
In
this example, fp is a pointer to a function that
returns int. You can rewrite the declaration of fp without
using a trailing return type as int (*fp)(void).
For more information on trailing return type, see Trailing return type (C++11).Under z/OS XL C/C++, if you pass a function pointer to a function, or the function returns a function pointer, the declared or implied linkages must be the same. Use the extern keyword with declarations in order to specify different linkages.
#include <stdlib.h>
extern "C" int cf();
extern "C++" int cxxf(); // C++ is included here for clarity;
// it is not required; if it is
// omitted, cxxf() will still have
// C++ linkage.
extern "C" int (*c_fp)();
extern "C++" int (*cxx_fp)();
typedef int (*dft_fp_T)();
typedef int (dft_f_T)();
extern "C" {
typedef void (*cfp_T)();
typedef int (*cf_pT)();
void cfn();
void (*cfp)();
}
extern "C++" {
typedef int (*cxxf_pT)();
void cxxfn();
void (*cxxfp)();
}
extern "C" void f_cprm(int (*f)()) {
int (*s)() = cxxf; // error, incompatible linkages-cxxf has
// C++ linkage, s has C linkage as it
// is included in the extern "C" wrapper
cxxf_pT j = cxxf; // valid, both have C++ linkage
int (*i)() = cf; // valid, both have C linkage
}
extern "C++" void f_cxprm(int (*f)()) {
int (*s)() = cf; // error, incompatible linkages-cf has C
// linkage, s has C++ linkage as it is
// included in the extern "C++" wrapper
int (*i)() = cxxf; // valid, both have C++ linkage
cf_pT j = cf; // valid, both have C linkage
}
main() {
c_fp = cxxf; // error - c_fp has C linkage and cxxf has
// C++ linkage
cxx_fp = cf; // error - cxx_fp has C++ linkage and
// cf has C linkage
dft_fp_T dftfpT1 = cf; // error - dftfpT1 has C++ linkage and
// cf has C linkage
dft_f_T *dftfT3 = cf; // error - dftfT3 has C++ linkage and
// cf has C linkage
dft_fp_T dftfpT5 = cxxf; // valid
dft_f_T *dftfT6 = cxxf; // valid
c_fp = cf; // valid
cxx_fp = cxxf; // valid
f_cprm(cf); // valid
f_cxprm(cxxf); // valid
// The following errors are due to incompatible linkage of function
// arguments, type conversion not possible
f_cprm(cxxf); // error - f_cprm expects a parameter with
// C linkage, but cxxf has C++ linkage
f_cxprm(cf); // error - f_cxprm expects a parameter
// with C++ linkage, but cf has C linkage
}
For z/OS, linkage compatibility affects all C library functions that accept a function pointer as a parameter.
References to functions
int g();
// f is a reference to a function that has no parameters and returns int.
int bar(int(&f)()){
// call function f that is passed as an argument.
return f();
}
int x = bar(g);
auto(&fp)()->int;