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.

A declaration of a pointer to a function must have the pointer name in parentheses. Function parameters have precedence over pointers in declarations, so parentheses are required to alter the precedence and declare a pointer to a function. Without them, the compiler interprets the declaration as a function that returns a pointer to a specified return type. For example:
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.

C++11
You can use a trailing return type in the declaration or definition of a pointer to a function. For example:
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).
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.

The following example illustrates the correct and incorrect uses of function pointers under z/OS XL C/C++ :
#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

A reference to a function is an alias or an alternative name for a function. You must initialize all references to functions after they are defined. Once defined, a reference to a function cannot be reassigned. You can use references to call functions and to pass functions as arguments to other functions. For example:
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);
C++11
You can also use a trailing return type in the declaration or definition of a reference to a function. In the following example, fp is a reference to a function that returns int. For more information on trailing return type, see Trailing return type (C++11).
auto(&fp)()->int;
C++11