Help me understand the following prototype. What is the last (int) doing?
void ( *signal(int sig, void (*handler)(int)) ) (int);
Help me understand the following prototype. What is the last (int) doing?
void ( *signal(int sig, void (*handler)(int)) ) (int);
Find the leftmost identifier and work your way out, remembering that [] and () bind before *; IOW, *a[] is an array of pointers, (*a)[] is a pointer to an array, *f() is a function returning a pointer, and (*f)() is a pointer to a function. Thus,
void ( *signal(int sig, void (*handler)(int)) ) (int);
breaks down as
signal -- signal
signal( ) -- is a function
signal( sig ) -- with a parameter named sig
signal(int sig, ) -- of type int
signal(int sig, handler ) -- and a parameter named handler
signal(int sig, *handler ) -- which is a pointer
signal(int sig, (*handler)( )) ) -- to a function
signal(int sig, (*handler)(int)) ) -- taking an int parameter
signal(int sig, void (*handler)(int)) ) -- and returning void
*signal(int sig, void (*handler)(int)) ) -- returning a pointer
( *signal(int sig, void (*handler)(int)) )( ) -- to a function
( *signal(int sig, void (*handler)(int)) )(int) -- taking an int parameter
void ( *signal(int sig, void (*handler)(int)) )(int); -- and returning void
The signal function associates a signal (sig) with a callback function (handler), like so:
#include <signal.h>
static int interrupt = 0;
/**
* The following function will be called when a SIGINT is
* detected (such as when someone types Ctrl-C)
*/
void interrupt_handler( int sig )
{
interrupt = 1;
}
int main( void )
{
/**
* Declare a pointer to the old interrupt handler function
*/
void (*old_interrupt_handler )(int);
/**
* Save the old interrupt handler while setting the new one
*/
old_interrupt_handler = signal( SIGINT, interrupt_handler );
while ( !interrupt )
{
// do stuff until someone hits Ctrl-C
};
/**
* restore the original interrupt handler
*/
signal( SIGINT, old_interrupt_handler );
return 0;
}
The whole thing declares a function called signal:
signal takes an int and a function pointer
int and returns voidsignal returns a function pointer
int and returns a voidThat's where the last int comes in.
You can use the spiral rule to make sense of such declarations, or the program cdecl(1).
As I pointed out in an answer to another recent question, one way to understand these declarations is to swap parameter lists and array declarators with the thing to their left and then read the declaration backwards. In this case that gives you
void ( *signal(int sig, void (*handler)(int)) ) (int)
->
void (int)( *(int sig, void (int)(*handler))signal )
Which reads as "`signal is a function that takes two parameters and returns a pointer to a function that takes an int parameter and returns void". The two parameters are an int (sig) and a pointer (handler) to a function that takes an int parameter and returns void.
Or you can do the swapping mentally, which is the same as the spiral rule.
void (*handler)(int); handler is pointer to a function (say Fn1) with return type voidand takes an int
void (*signal(int sig, Fn1)) (int);
(*signal(int sig, Fn1); This function has return type void and takes an int and function pointer as arguments.
The return type of this function, whose pointer is signal is possibly a function pointer for a function that takes an int[final int] with return type void
The above prototype can be written as::
typedef void (*sig_t) (int);
sig_t signal(int sig, sig_t handler);
Now, I hope it would be clear to you.
it is a function returning a pointer to a function returning void..Source:" Unscrambling C Declarations " in DEEP C SECRETS