Complicated declarations in C - GeeksforGeeks

05 Mar, 2021
Most of the times declarations are simple to read, but it is hard to read some declarations which involve pointer to functions. For example, consider the following declaration from “signal.h”.
C
void (*bsd_signal(int, void (*)(int)))(int);
Let us see the steps to read complicated declarations.1) Convert C declaration to postfix format and read from right to left. 2) To convert expression to postfix, start from innermost parenthesis, If innermost parenthesis is not present then start from declarations name and go right first. When first ending parenthesis encounters then go left. Once whole parenthesis is parsed then come out from parenthesis. 3) Continue until complete declaration has been parsed.Let us start with simple example. Below examples are from “K & R” book.
C
1)  int (*fp) ();
Let us convert above expression to postfix format. For the above example, there is no innermost parenthesis, that’s why, we will print declaration name i.e. “fp”. Next step is, go to right side of expression, but there is nothing on right side of “fp” to parse, that’s why go to left side. On left side we found “*”, now print “*” and come out of parenthesis. We will get postfix expression as below.  
  fp  *  ()  int
Now read postfix expression from left to right. e.g. fp is pointer to function returning int
C
/* Example */ #include <stdio.h>int (*fp)();int func(void) { printf("hello\n"); } int main(){    fp = func;    (*fp)();    // fp(); // This will also call func    return 0;}
hello
Let us see some more examples.  
C
2) int (*daytab)[13]
Postfix : daytab * [13] int Meaning : daytab is pointer to array of 13 integers.
C
/* Example */ #include <stdio.h>int (*daytab)[13];int arr[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };int main(){    daytab = &arr;    printf("arr[2] = %d\n", (*daytab)[2]);    return 0;}
arr[2] = 3
 
C
3) void (*f[10]) (int, int)
Postfix : f[10] * (int, int) void Meaning : f is an array of 10 pointer to function(which takes 2 arguments of type int) returning void 
C
/* Example */ #include <stdio.h>void (*f[10])(int, int);void func1(int a, int b){    printf("func1 = %d, %d\n", a, b);}void func2(int p, int q){    printf("func2 = %d, %d\n", p, q);}void func3(int x, int y){    printf("func3 = %d, %d\n", x, y);}int main(){    f[0] = func1;    f[1] = func2;    f[2] = func3;    (*f[0])(1, 2);    (*f[1])(3, 4);    (*f[2])(5, 6);    return 0;}
func1 = 1, 2
func2 = 3, 4
func3 = 5, 6
C
4) char (*(*x())[]) ()
Postfix : x () * [] * () char Meaning : x is a function returning pointer to array of pointers to function returning char
C
/* Example */ #include <stdio.h>char func1() { return 'a'; }char func2() { return 'b'; }char func3() { return 'c'; } char (*xarr[])() = { func1, func2, func3 };char (*(*x())[])() { return &xarr; } int main(){    printf("%c\n", ((*(x()))[0])());    printf("%c\n", ((*(x()))[1])());    printf("%c\n", ((*(x()))[2])());    return 0;}
a
b
c
 
C
5) char (*(*x[3])())[5]
Postfix : x[3] * () * [5] char Meaning : x is an array of 3 pointers to function returning pointer to array of 5 char’s
C
/* Example */ #include <stdio.h> typedef char charray5[5]; charray5 carr1 = { 'a', 'b', 'c', 'd', '\0' };charray5 carr2 = { 'q', 'w', 'e', 'r', '\0' };charray5 carr3 = { 'x', 'y', 'z', 'w', '\0' }; charray5* func1() { return &carr1; }charray5* func2() { return &carr2; }charray5* func3() { return &carr3; } char (*(*x[3])())[5] = { func1, func2, func3 }; int main(){    printf("func1 = [%c, %c, %c, %c]\n",           ((*(x[0]))())[0][0], ((*(x[0]))())[0][1],           ((*(x[0]))())[0][2], ((*(x[0]))())[0][3]);    printf("func2 = [%c, %c, %c, %c]\n",           ((*(x[1]))())[0][0], ((*(x[1]))())[0][1],           ((*(x[1]))())[0][2], ((*(x[1]))())[0][3]);    printf("func3 = [%c, %c, %c, %c]\n",           ((*(x[2]))())[0][0], ((*(x[2]))())[0][1],           ((*(x[2]))())[0][2], ((*(x[2]))())[0][3]);    return 0;}
func1 = [a, b, c, d]
func2 = [q, w, e, r]
func3 = [x, y, z, w]
 
C
6) int *(*(*arr[5])()) ()
Postfix : arr[5] * () * () * int Meaning : arr is an array of 5 pointers to functions returning pointer to function returning pointer to integer 
C
/* Example */ #include <stdio.h> int a = 1;int b = 2;int* func1() { return &a; }int* func2() { return &b; } int* (*funcp1())() { return func1; }int* (*funcp2())() { return func2; }int* (*(*arr[5])())() = { funcp1, funcp2 }; int main(){    printf("%d\n", *(*(*arr[0])())());    printf("%d\n", *(*(*arr[1])())());    return 0;}
1
2
C
7) void (*bsd_signal(int sig, void (*func)(int)))(int);
Postfix : bsd_signal(int sig, void(*func)(int)) * (int) void Meaning : bsd_signal is a function that takes integer & a pointer to a function(that takes integer as argument and returns void) and returns pointer to a function(that take integer as argument and returns void)
C
#include <stdio.h> void on_sig10_exit(int u) { printf("sig10 exit\n"); }void on_sig20_exit(int u) { printf("sig20 exit\n"); }void default_exit(int u) { printf("default exit\n"); }void user_default_exit(int u){    printf("user default exit\n");} void (*exit_by)(int); void (*bsd_signal(int sig, void (*func)(int)))(int){    switch (sig) {    case 10:        return on_sig10_exit;    case 20:        return on_sig20_exit;    default:        if (func == NULL)            return default_exit;        else            return user_default_exit;    }} int main(){    (bsd_signal(10, NULL))(0);    (bsd_signal(20, NULL))(0);    (bsd_signal(30, NULL))(0);    (bsd_signal(30, user_default_exit))(0);    return 0;}
sig10 exit
sig20 exit
default exit
user default exit
This article is compiled by “Narendra Kangralkar“ and reviewed by GeeksforGeeks team. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
Karthiik
aakash nandi
vaghelasunil09
C-Variable Declaration and Scope
pointer
C Language
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Command line arguments in C/C++
fork() in C
Different methods to reverse a string in C/C++
Function Pointer in C
TCP Server-Client implementation in C
Substring in C++
Enumeration (or enum) in C
Structures in C
std::string class in C++
Exception Handling in C++