James
James

Reputation: 2463

Embedded Function Pointers

I'm having trouble understanding this specific declaration:

void (*signal(int, void (*fp)(int)))(int);

My previous understanding of function pointers was that the first item in brackets was the name of the function pointer.

eg int (*MySuperDuperNameForASimpleAddFunction)(int, int);

I don't understand how it's possible to have anything other than identifiers in the first bracket.

Upvotes: 1

Views: 735

Answers (3)

user3793679
user3793679

Reputation:

The following was accepted by gcc:

static void (*signal(int, void (*fp)(int)))(int) ;

typedef void (sigfunc)(int) ;
static sigfunc* signal(int i, sigfunc* fp)
{
  fp(i) ;
  return fp ;
} ;

I have no idea why the return value from the signal function has to be wrapped around its definition in this way... and I suspect life is too short to allow me to discover !

I tried static void (*fp)(int) signal(int, void (*fp)(int)) but the computer said NO.

Upvotes: 0

John Bode
John Bode

Reputation: 123458

Standard rule: find the leftmost identifier, then work your way out remembering that function-call () and [] bind before *, so *a[] is an array of pointers, (*a)[] is a pointer to an array, *f() is a function returning a pointer, and (*f)() is a pointer to a function. Apply this rule recursively for any function parameters.

With all that in mind, the declaration breaks down like so:

       signal                               -- signal
       signal(                    )         -- is a function taking
       signal(int,                )         --   an int parameter and
       signal(int,        fp      )         --   a parameter named fp of type
       signal(int,      (*fp)     )         --     pointer to
       signal(int,      (*fp)(   ))         --       function taking 
       signal(int,      (*fp)(int))         --         an int parameter
       signal(int, void (*fp)(int))         --         returning void
     (*signal(int, void (*fp)(int)))        --   returning a pointer to
     (*signal(int, void (*fp)(int)))(   )   --     a function taking
     (*signal(int, void (*fp)(int)))(int)   --       an int parameter
void (*signal(int, void (*fp)(int)))(int);  --       returning void

So, signal takes two arguments, one of which is a pointer to a function taking an int and returning void, and returns a pointer to a function of the same type as fp.

Upvotes: 2

Quentin
Quentin

Reputation: 63124

void (*signal(int, void (*fp)(int)))(int);

signal is a function, taking :

  • an int
  • a function pointer taking an int and returning void

...and returning a function pointer taking an int and returning void. Phew.

Upvotes: 5

Related Questions