theartist33
theartist33

Reputation: 482

How to declare pointer pointing to function which returns function pointer

I have below code running fine and giving out expected result. I have an additional query that how can I declare a pointer in my main function that holds the address of function A(funcA) ?

#include<stdio.h>
#include<stdlib.h>


int funcB (void)
{
 printf("\n Now you are in function B \n ");

 printf ("\n this function is for returning code value no matter what\n");

 return -10;
}

int (*funcA(int x,int y)) (void)
{
 printf( " I am in function A \n ");
   static int sum;
   sum=x+y;
 printf ( "\n Sum is %d ",sum);
 return &funcB;
 }

int main ()

{

int (*fpb)(void);

int x;

fpb=funcA(10,15);

x=(*fpb)();   // Calling function B through fpb pointer

printf("\n Value stored in x for code is %d \n",x);

}

Result :

I am in function A

Sum is 25
Now you are in function B

this function is for returning code value no matter what

Value stored in x for code is -10

Upvotes: 3

Views: 233

Answers (7)

John Bode
John Bode

Reputation: 123596

To figure out the type for a pointer to funcA, take the declaration of funcA:

int (*funcA(int x,int y)) (void)

and replace funcA with (*fptr), so your declaration becomes

int (*(*fptr)(int x, int y))(void);

which reads as

        fptr                          -- fptr
       *fptr                          -- is a pointer
      (*fptr)(            )           -- to a function with
      (*fptr)(    x,      )           -- parameter x
      (*fptr)(int x,      )           --   is an int
      (*fptr)(int x,     y)           -- parameter y
      (*fptr)(int x, int y)           --   is an int
     *(*fptr)(int x, int y)           -- returning a pointer
    (*(*fptr)(int x, int y))(    )    -- to a function with
    (*(*fptr)(int x, int y))(void)    -- no parameters
int (*(*fptr)(int x, int y))(void);   -- returning int

You'd assign it as

fptr = funcA;

and call it as

int x = (*(*fptr)(a,b))();

Note that while some of us1 find this kind of declaration perfectly transparent, most C programmers don't obsess over declaration syntax to this level and prefer to hide most of that complexity behind typedefs:

typedef int fb(void);
typedef fb *fa(int x, int y);

fa *fptr = funcA;

However, that declaration doesn't really tell you how to use fptr in an expression, whereas

int (*(*fptr)(int x, int y))(void);

is pretty unambiguous:

int x = (*(*fptr)(a,b))();


1. I will cheerfully admit I'm an outlier in this regard; I once wrote some code that did pretty much what the fptr call above does (that is, call multiple functions through pointers in a single expression) and thought it was crystal-clear. My coworkers quickly reminded me that I'm weird and insisted I break those into separate statements.

Upvotes: 2

songyuanyao
songyuanyao

Reputation: 173044

how can I declare a pointer in my main function that holds the address of function A(funcA) ?

  1. You could write it directly (and uglily):

    int (*(*fpa)(int,int)) (void) = &funcA;

  2. You could use typedef to make it clear:

    typedef int (*FPB)(void);
    typedef FPB (*FPA)(int, int);
    FPA fpa = &funcA;

  3. Because you tagged c++, you could use auto specifier (since c++11) to make it direct and clear:

    auto fpa = &funcA;

Upvotes: 4

Lukas
Lukas

Reputation: 1305

It is also worth mentioning that you can also use std::function (c++11). However, this is not a function pointer, but rather a wrapper that can hold any callable object. This is a more heavier approach compared to simple pointers.

If function pointers are enough for your case and you don't need to manage a lot of functions then I would definitely recommend to use function pointers.

(http://en.cppreference.com/w/cpp/utility/functional/function)

#include <cstdio>
#include <cstdlib>
#include <functional>


int funcB()
{
  printf("\n Now you are in function B \n ");
  printf("\n this function is for returning code value no matter what\n");
  return -10;
}

std::function<int(void)> funcA(int x, int y)
{
  printf(" I am in function A \n ");
  static int sum;
  sum = x + y;
  printf("\n Sum is %d ", sum);
  return funcB;
}

int main()
{
  std::function<std::function<int(void)>(int, int)> func_a = funcA;
  std::function<int(void)> func_b = func_a(10, 15);
  int x = func_b();

  printf("\n Value stored in x for code is %d \n", x);

  return 0;
}

Upvotes: 1

pmg
pmg

Reputation: 108986

Use a few typedefs

#include <stdio.h>
#include <stdlib.h>

int funcB(void) {
    printf("Now you are in function B\n");
    printf("this function is for returning code value no matter what\n");
    return -10;
}

int (*funcA(int x,int y)) (void) {
    printf("I am in function A\n");
    static int sum;
    sum = x + y;
    printf("Sum is %d\n", sum);
    return &funcB;
}

// typedefs to make life easier    
typedef int (ta)(void);
typedef ta *(tb)(int, int); // use previous typedef'd ta

int main(void) {
    int x, y;
    ta *fpb;
    tb *fpa;

    fpb = funcA(10, 15);
    fpa = funcA;
    x = fpb();   // Calling function B through fpb pointer
    y = fpa(10, 15)(); // calling function B through pointer to function A

    printf("Value stored in x for code is %d\n", x);
    printf("Value stored in y for code is %d\n", y);

    return 0;
}

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 755084

How do I declare a pointer that can hold a pointer to funcA?

Unless you're very brave (and I'm too lazy to be that brave), you use a typedef for the pointer to FuncB type:

typedef int (*FunctionReturningInt)(void);

Now, funcA is a function returning a FunctionReturningInt:

extern FunctionReturningInt funcA(int x, int y);

To create a pointer to that:

FunctionReturningInt (*funcA_ptr)(int x, int y) = funcA;

Upvotes: 1

First rule of declaring "pointers to function" is "use a typedef". You will be grateful when you come back in two weeks time, and try to work out what the hell is going on.

typedef void (*pfuncB_t)();  // (void) is a C-compatability hack.  Use () in C++.

so funcA's declaration becomes a lot easier to read:

pfuncB_t funcA(int x, int y);

... and declaring a type for a pointer to funcA is also easy.

typedef pfuncB_t (*pfuncA_t)(int, int);

and you can use it like:

pfuncA_t globalA = &funcA;   // You don't need the address-of, but it is legal.

Upvotes: 1

Topological Sort
Topological Sort

Reputation: 2898

The syntax is grokky enough that it's best to use a typedef. I'm not assuming C++11. The ()s go around *NameOfType:

typedef int (*funcBTypePointer) (void);

int main ()
{
    funcBTypePointer fpb;

    ...
}

I see that funcA is to return the address of funcB. Here's how to do that:

funcBTypePointer funcA(int x,int y)
{
 printf( " I am in function A \n ");
 static int sum;
 sum=x+y;
 printf ( "\n Sum is %d ",sum);
 return funcB;
}

If you refer to a function without an argument list, you get a pointer to the function; & is not needed.

For more information on function pointers, see this tutorial: http://www.learncpp.com/cpp-tutorial/78-function-pointers/

Upvotes: 3

Related Questions