## Pointer Declarator

Here is a fun puzzle that involves complex type declarations in C:

Without using `typedef`, declare `x` as a pointer to a function that takes one argument which is an array of 10 pointers to functions which in turn take `int *` as their only argument and returns a pointer to a function which has `int *` argument and `void` return type.

Here is a simpler way to state this puzzle:

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

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

If you want to think about this puzzle, this is a good time to pause and think about it. There are spoilers ahead.

Let me describe how I solve such problems. Let us start from the right end of the problem and work our way to the left end defining each part one by one.

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

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

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

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

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

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

## Example Code

Here is an example that uses the above pointer declaration in a program in order to verify that it works as expected:

    #include <stdio.h>

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

    /* A function which has an array of 10 pointers to g()-like functions
       and returns a pointer to a g()-like funciton.  */
    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 g().  */
        void (*a[10])(int *) = {g, g, g, g, g, g, g, g, g, g};

        /* A pointer to function f().  */
        void (*(*x)(void (*[10])(int *)))(int *) = f;

        /* A pointer to function g() returned by f().  */
        void (*y)(int *a) = x(a);

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

Here is the output of this program:

    $ gcc -Wall -Wextra -pedantic -std=c99 foo.c && ./a.out
    g(): a = 0
    g(): a = 1
    g(): a = 2
    g(): a = 3
    g(): a = 4
    g(): a = 5
    g(): a = 6
    g(): a = 7
    g(): a = 8
    g(): a = 9
    g(): a = 10

## Further Reading

The book The C Programming Language, Second Edition has some good examples of complicated declarations of pointers in Section 5.12 (Complicated Declarations). Here are a couple of them:

`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