Reputation: 593
In <signal.h>
there are definition of following:
#define SIG_ERR (void (*)())-1
#define SIG_DFL (void (*)())0
#define SIG_IGN (void (*)())1
I think void (*)()
means it's a function pointer that return type is void and parameter is void(because there is empty between parenthesis).
But in signal()
function, the second argument type is void (*func)(int)
.
Then, why the definition above three things are void (*)()
. And, also, what means the number -1
0
1
in the definition?
How can I interpret these definitions?
Upvotes: 7
Views: 4689
Reputation: 7506
How can I interpret these definitions?
#define SIG_DFL (void (*)()) 0
is merely an ordinary #define
with casting.
You must know #define HAHA 2
(a int
with value 2),
so what about #define HAHA (float) 2
(a float
with value 2) ,
and #define HAHA (int*) 2
(a pointer to int
/int*
with value(the pointer's value) 2).
So #define SIG_DFL (void (*)()) 0
means it's defining a (function) pointer, and the pointer's value is 0
.
Again, SIG_DFL
is a constant with value 2
, and its type is void(*)(int)
, a (function) pointer.
As for function pointers, it's something you can call directly.
#include <stdio.h>
void foo(int a){
printf("%d\n", a);
printf("hahaha\n");
}
int main(){
foo(3); //you can call foo() directly
//or you may call it through a matched function pointer
void (*foo_ptr)(int); // I am declaring a function pointer
foo_ptr = foo;
foo_ptr(3); //same as calling foo(3)
}
Why the definition above three things are
void (*)()
?
Because it's what the signal
function requires. The signal
function requires its handlers to have function signature like void (*)(int)
.
So the fake functions (SIG_DFL
, SIG_IGN
) also need to be the void (*)(int)
type.
Note the SIG_ERR
is used to indicate a handler setting failure.
See the parameter description of handler from https://en.cppreference.com/w/c/program/signal.
What does the number -1 0 1 in the definition mean?
See What 's the meaning of the number 1 in SIG_IGN macro definition?
I have to say at first I was mainly stuck in the pattern #define SIG_DFL (void (*)()) 0
, I didn't realize it is a casting.. :)
Upvotes: 1
Reputation: 133849
Your definitions are different from mine. If I preprocess the following file:
#include <signal.h>
SIG_IGN
SIG_DFL
SIG_ERR
The last 3 lines in the preprocessor output are
% gcc -E sigtest.c|tail -n3
((__sighandler_t) 1)
((__sighandler_t) 0)
((__sighandler_t) -1)
and the typedefs are
typedef __signalfn_t *__sighandler_t;
and
typedef void __signalfn_t(int);
from asm-generic/signal-defs.h
. So it must be that you have some old headers.
However, this is not C++, but C. Empty parentheses in C mean that the function arguments are not declared / that the function can take any number of arguments. This has been considered obsolescent since C89 standard. Yet, a value of type void (*)()
would be compatible with void (*)(int)
.
The values -1, 0 and 1 are non-portable magic constants that have meaning only to the Linux kernel.
Upvotes: 4