## Clumsy pointers

Here is a silly puzzle I solved exactly one month ago.

Without using typedef, declare a pointer to a function which has an array of 10 pointers to functions which have int * argument and return type void as argument, and returns a pointer to a function which has int * argument and return type void.

If the above problem statement is difficult to understand, here is the same problem expressed in terms of typedef.

Without using typedef, declare a pointer that is equivalent to the following declaration of x.

typedef void (*func_t)(int *);
func_t (*x)(func_t [10]);


I'll describe how I solve such problems. I start from the right end of the problem and work my way to the left most end defining each part one by one.

Let me start.

void x(int *)
A function which has int * argument and return type void.

void (*x)(int *)
Pointer to a function which has int * argument and return type void.

void (*x())(int *)
A function that returns a pointer to a function which has int * argument and return type void.

void (*x(void (*)(int *)))(int *)
A function which has a pointer to a function that has int * argument and return type void as argument, and returns a pointer to a function which has int * argument and return type void.

void (*x(void (*[10])(int *)))(int *)
A function which has an array of 10 pointers to functions that has int * argument and return type void as argument, and returns a pointer to a function which has int * argument and return type void.

void (*(*x)(void (*[10])(int *)))(int *)
A pointer to a function which has an array of 10 pointers to functions that has int * argument and return type void as argument, and returns a pointer to a function which has int * argument and return type void.

I verified the declaration with a short code.

#include <stdio.h>

/* A function which has int * argument and return type void. */
void g(int *a)
{
printf("g(): a = %d\n", *a);
}

/* A function which has an array of 10 pointers to functions that has
* int * argument and return type void as argument, and returns a
* pointer to a function which has int * argument and return type void.
*/
void (*f(void (*a[10])(int *)))(int *)
{
int i;
for (i = 0; i < 10; i++)
a[i](&i);
return g;
}

int main()
{
/* An array of 10 pointers to functions that has int * argument and
* return type void. */
void (*a[10])(int *) = {g, g, g, g, g, g, g, g, g, g};

/* A pointer to the function which has an array of 10 pointers to
* functions that has int * argument and return type void as
* argument, and returns a pointer to a function which has int *
* argument and return type void. */
void (*(*x)(void (*[10])(int *)))(int *) = f;

/* A pointer to a function that has int * argument and return type
* void. */
void (*y)(int *a) = x(a);

int i = 10;
y(&i);
return 0;
}


Section 5.12 (Complicated Declarations) of the second edition of The C Programming Language by and has some good examples of complicated declarations of pointers although they are less clumsy than the one in this blog post. Let me mention a couple of interesting ones from that section.

char (*(*x())[])()
x: function returning pointer to array[] of pointer to function returning char.

char (*(*x[3])())[5]
x: array[3] of pointer to function returning pointer to array[5] of char.

#### Mandeep said:

Nice! The syntax on "returning" function pointers was a little tricky. Learnt that today! :)

#### Iouri said:

There is a website that you can use for that: http://cdecl.org/

It can take "declare x as pointer to function (array 10 of pointer to function (pointer to int) returning void) returning pointer to function (pointer to int) returning void" and give back

void (*(*x)(void (*[10])(int *)))(int *)

#### Michael said:

I wrote a simple C parser once, and found this page to be very helpful in understanding complex C declarators: http://msdn.microsoft.com/en-us/library/1x82y1z4.aspx

#### Peter Desnoyers said:

See R. P. Mody. 1992. "On understanding type declarations in C." SIGPLAN Not. 27, 6 (June 1992), 80-83.

It gives a short calculus for understanding pre-ANSI type declarations. Best quote from it: "We are now ready to tackle a famous horror — 'signal' of UNIX".