Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Messy function pointer interpretation

I happen to come across the following function pointer.

char (*(*x())[])();

It looks like an array of function pointer in the following format, but I can't see what f -> (*x()) means. How to interpret this messy function pointer?

char (*f[])();

ADDED

With John Bode's help, I make an example as follows.

#include <stdio.h>

char foo()    { return 'a'; }
char bar()    { return 'b'; }
char blurga() { return 'c'; }
char bletch() { return 'd'; }

char (*gfunclist[])() = {foo, bar, blurga, bletch};

char (*(*x())[])()
{
  static char (*funclist[4])() = {foo, bar, blurga, bletch};
  return &funclist;
}

int main() 
{
  printf("%c\n",gfunclist[0]());

  char (*(*fs)[4])();
  fs = x();
  printf("%c\n",(*fs)[1]()); 
}

I could get the expected result.

smcho@prosseek temp2> ./a.out 
a
b

And, you can find a better implementation here.

like image 296
prosseek Avatar asked Nov 05 '10 13:11

prosseek


People also ask

What is function pointer and explanation?

A function pointer, also called a subroutine pointer or procedure pointer, is a pointer that points to a function. As opposed to referencing a data value, a function pointer points to executable code within memory.

What is the advantage of function pointer in C?

Function pointers are used as callbacks in many cases. One use is as a comparison function in sorting algorithms. So if you are trying to compare customized objects, you can provide a function pointer to the comparison function that knows how to handle that data.


5 Answers

My general procedure is to find the leftmost identifier in the declaration, and then work my way out, remembering that [] and () bind before * (i.e., *f() is normally parsed as *(f()) and *a[] is normally parsed as *(a[])).

So,

          x           -- x
          x()         -- is a function
         *x()         -- returning a pointer
        (*x())[]      -- to an array
       *(*x())[]      -- of pointers
      (*(*x())[])()   -- to functions
 char (*(*x())[])();  -- returning char

What would such a beast look like in practice?

char foo()    { return 'a'; }
char bar()    { return 'b'; }
char blurga() { return 'c'; }
char bletch() { return 'd'; }

/**  
 *           funclist           -- funclist
 *           funclist[]         -- is an array
 *          *funclist[]         -- of pointers
 *         (*funclist[])()      -- to functions
 *    char (*funclist[])()      -- returning char
 */    
char (*funclist[])() = {foo, bar, blurga, bletch};

The expression &funclist will return a pointer to the array, so

char (*(*x())[])()
{
  return &funclist;
}
like image 140
John Bode Avatar answered Oct 03 '22 23:10

John Bode


char (*(*x())[])();

x is a function returning pointer to array of pointer to function returning char

char (*f[])();

In this case f is an array of pointer to function returning char

Using the right-left rule would be beneficial.

like image 45
Prasoon Saurav Avatar answered Oct 04 '22 00:10

Prasoon Saurav


cdecl> explain char (*(*x())[])();
declare x as function returning pointer to array of pointer to function returning char
like image 28
user470379 Avatar answered Oct 04 '22 01:10

user470379


A few typedefs make it clearer:

typedef char (*charfunc_t)();

This defines charfunc_t to be a pointer to a function without arguments that returns char.

typedef charfunc_t funcarr_t[];

funcarr_t is an array of such function pointers.

x is a function returning a pointer to such an array and it can now be declared like this:

funcarr_t* x();
like image 40
sth Avatar answered Oct 04 '22 00:10

sth


Visit this site to help you understand c declarations (cdecl.org), if you type the above in, it will tell you this

declare x as function returning pointer to array of pointer to function returning char

like image 22
t0mm13b Avatar answered Oct 03 '22 23:10

t0mm13b