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 void
signal
returns a function pointer
int
and returns a void
That'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 void
and 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