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:

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]); Without using, declareas a pointer that is equivalent to the following declaration of

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.

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

", *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

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