Kushagra Varade
Kushagra Varade

Reputation: 87

Meaning of the following C declarations

I am unable to understand the following declaration can somebody please help me with this. It is bit confusing and I can't find any proper explanation for this expression plus I have never seen such type of declaration before in my practice.

char(*(*x())[])();
char(*(*x[3])())[5];
void (*b(int, void (*f)(int)))(int);
void (*ptr)(int(*)[2], int(*)(void));

Upvotes: 1

Views: 2546

Answers (2)

Holt
Holt

Reputation: 37606

You need to decompose them, the last two are easier:

char (*(*x())[])();
char (*x)();        // A pointer to a function returning char with any args.
char (*x[])();      // An array of such pointers.
char (*(*x)[])();   // A pointer to such array.
char (*(*x())[])(); // A function returning such pointer: A function returning a pointer to
                    // an array of pointer to function returning char with any args.

char(*(*x[3])())[5];
char(*x)();          // A pointer to a function returning char with any args.
char(*x)()[5];       // A pointer to a function returning an array of 5 chars (any args).
char((*x)())[5];     // Same as above.
char(*(*x)())[5];    // A pointer to a function returning a pointer to an array of 5 chars.
char(*(*x[3])())[5]; // An array of 3 of these pointers.

void (*b(int, void (*f)(int)))(int);
X b(int, void(*f)(int)); // A function returning X and taking an int and a pointer to
                         // a function f taking an int and returning nothing.
void (*b())(int); // A function taking nothing and returning a pointer to a function
                  // taking and int and returning nothing.
void (*b(int, void (*f)(int)))(int); // Combination of the two above, a function taking and
                                     // an int and a pointer to a function f and returning
                                     // a pointer to a function.

void(*ptr)(int(*)[2], int(*)(void)); // This one is easier:
void(*ptr)(); // A  pointer to a function with no args and returning nothing.
void(*ptr)(int(*)[2], int(*)(void)); // A pointer to a function returning nothing and taking:
                                     // - A pointer to an array of 2 int
                                     // - A pointer to a function returning int with no args.

You can check all these using cdecl.org.

Some tips when you need to decompose such declarations:

  1. A function returning a pointer to an array or to a function is not common, but you have to know how to declare them:
int (*f())[5];   // A function returning a pointer to an array of 5 int.
int (*f())(int); // A function returning a pointer to a function int (*)(int).

Notice that within these 2 declarations, part of the return type appears after the parameter list of the function, which is why those are often confusing when you encounter them for the first time.

  1. You can always remove the name of parameters in function:
int b(void(*f)(int), int(*p)[2]);
int b(void(*)(int), int(*)[2]); // Same as above
  1. If the name is directly next to a square-bracket, e.g. x[N], then it is an « array N of something »:
int (*x[3])();  // x is an array of 3 pointers to functions int(*)().
int (*x[4])[5]; // x is an array of 4 pointers to array of 5 int.
int (*x)[4];    // x is not an array.

Upvotes: 1

Nyakiba
Nyakiba

Reputation: 862

This looks like an evil example straight from the 2nd edition of Kernighan and Ritchie (The C Programming Language), p. 122 (section 5.12: Complicated Declarations), where it is described as a function returning a pointer to an array of pointers to functions returning char. Here is a usage example:

#include <stdio.h>

char x1() { return 'a'; } // Function returning a char
char (*x2[])() = {&x1}; // Array of pointers to functions returning  char
char (*(*x())[])() { return &x2; } // Function returning a pointer to the above

void main(){
    char (*x3)() = **x(); // Pointer to a function returning char
    printf("This is the value: %c\n", x3());
}

Upvotes: 0

Related Questions