how to use a function pointer in a cast to another function pointer

71 Views Asked by At

While working with very old minix sw (MINIX 1.5) I encountered weird function declarations; 1) the declaration of a function's prototype, and 2) the declaration of the function itself

/* in header file the prototype of a signal function, with my annotations */

     /*---is this some sort of casting ???---*/
             /*----two input arguments----*/
void (*signal(int sig,  void (*_func)(int) )  )  (int);

                        /*---func ptr---*/

I can only deduct a casting, but what is casted here and how would you describe the resulting function? The same definition is maintained in the code file, so we are definitely talking a function declaration, but its output is not clear to me. Refer to the next code snippet. Some reference to documentation is welcome.

/* in the code file */

PUBLIC void (*signal(int signr, void (*func)(int))) (int){
  void (*old) (int);

  /* there is more code, but not relevant for the problem */

return(old);
}



3

There are 3 best solutions below

0
Gerhardh On

Normally I would not advice to hide a pointer type in a typedef. This might be one of the exceptions.

You can make your life easier:

typedef void (*sig_func_type)(int);

sig_func_type signal(int sig, sig_func_type func);
0
dbush On

There's no cast here. What you have is a function that takes a function pointer as one of its arguments and returns a function pointer.

Linux uses a similar declaration, but the man page shows it using typedefs for the function pointers to make it more clear:

   typedef void (*sighandler_t)(int);

   sighandler_t signal(int signum, sighandler_t handler);
0
Eric Postpischil On

In void (*signal(int sig, void (*_func)(int) ) ) (int);, matching the first open parentheses with its close parentheses shows the form is void (…)(int);.

This declares a function with an int parameter and returning nothing (void).

Inside the parentheses, we have *signal(int sig, void (*_func)(int) ). Again matching the first open parentheses to its close parentheses gives the form *signal(), so we see this is a function returning a pointer to the surrounding type, which we know from above is a function with an int parameter returning void.

Therefore signal is a function that returns a pointer to a function with an int parameter returning void.

Looking inside the parentheses after signal, we know these are the parameters to the function signal, and they are int sig and void (*_func)(int).

int sig clearly declares an int parameter. void (*_func)(int) declares (*_func) to be a function taking an int parameter and returning void. Since (*_func) is a function, _func is a pointer to a function.

So the entire declaration declares signal to be a function that takes a first parameter that is an int and a second parameter that is a pointer to a function taking an int parameter and returning void, and signal returns a pointer to a function taking an int parameter and returning void.

If you call a function that takes an int parameter and returns void a “signal handler,” then signal is a function that takes an int and a pointer to a signal handler and that returns a pointer to a signal handler.