Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you explain the following C/C++ statement?

void (*func)(int(*[ ])());
like image 655
arunachalam Avatar asked Nov 06 '09 12:11

arunachalam


2 Answers

The general procedure for reading hairy declarators is to find the leftmost identifier and work your way out, remembering that [] and () bind before * (i.e., *a[] is an array of pointer, not a pointer to an array). This case is made a little more difficult by the lack of an identifier in the parameter list, but again, [] binds before *, so we know that *[] indicates an array of poitners.

So, given

void (*func)(int(*[ ])());

we break it down as follows:

       func                   -- func
      *func                   -- is a pointer
     (*func)(           )     -- to a function taking
     (*func)(     [ ]   )     --    an array
     (*func)(    *[ ]   )     --    of pointers
     (*func)(   (*[ ])())     --    to functions taking 
                              --      an unspecified number of parameters
     (*func)(int(*[ ])())     --    returning int
void (*func)(int(*[ ])());    -- and returning void

What this would look like in practice would be something like the following:

/**
 * Define the functions that will be part of the function array
 */
int foo() { int i; ...; return i; }
int bar() { int j; ...; return j; }
int baz() { int k; ...; return k; }
/**
 * Define a function that takes the array of pointers to functions
 */
void blurga(int (*fa[])())
{
  int i;
  int x;
  for (i = 0; fa[i] != NULL; i++)
  {
    x = fa[i](); /* or x = (*fa[i])(); */
    ...
  }
}    
...
/**
 * Declare and initialize an array of pointers to functions returning int
 */
int (*funcArray[])() = {foo, bar, baz, NULL};
/**
 * Declare our function pointer
 */
void (*func)(int(*[ ])());
/**
 * Assign the function pointer
 */
func = blurga;
/**
 * Call the function "blurga" through the function pointer "func"
 */
func(funcArray); /* or (*func)(funcArray); */
like image 102
John Bode Avatar answered Sep 18 '22 06:09

John Bode


It's not a statement, it's a declaration.

It declares func as a pointer to a function returning void and taking a single argument of type int (*[])(), which itself is a pointer to a pointer to a function returning int and taking a fixed but unspecified number of arguments.


cdecl output for ye of little faith:

cdecl> explain void (*f)(int(*[ ])());
declare f as pointer to function (array of pointer to function returning int) returning void
like image 25
caf Avatar answered Sep 21 '22 06:09

caf