在<signal.h>
中有以下定义:
#define SIG_ERR (void (*)())-1
#define SIG_DFL (void (*)())0
#define SIG_IGN (void (*)())1
我认为void (*)()
表示它是一个函数指针,返回类型为void,参数为void(因为括号之间有空)。
但是在signal()
函数中,第二个参数类型是void (*func)(int)
。
然后,为什么以上三个方面的定义是void (*)()
。而且,定义中的数字-1
0
1
是什么意思?
我如何解释这些定义?
答案 0 :(得分:3)
您的定义与我的不同。如果我预处理以下文件:
#include <signal.h>
SIG_IGN
SIG_DFL
SIG_ERR
预处理器输出中的最后3行是
% gcc -E sigtest.c|tail -n3
((__sighandler_t) 1)
((__sighandler_t) 0)
((__sighandler_t) -1)
并且typedef是
typedef __signalfn_t *__sighandler_t;
和
typedef void __signalfn_t(int);
来自asm-generic/signal-defs.h
。所以一定是你有一些旧的标题。
但是,这不是C ++,而是C.C中的空括号表示函数参数未声明/函数可以使用任意数量的参数。自C89标准以来,这被认为是过时的。但是,类型void (*)()
的值与void (*)(int)
兼容。
值-1,0和1是非可移植的魔术常量,仅对Linux内核有意义。
答案 1 :(得分:0)
如何解释这些定义?
#define SIG_DFL (void (*)()) 0
仅仅是具有广播的普通#define
。
您必须知道#define HAHA 2
(一个值为{2的int
),
那么#define HAHA (float) 2
(一个值为{2的float
)呢,
和#define HAHA (int*) 2
(指向int
/ int*
的指针,其值(指针的值)为2)。
因此#define SIG_DFL (void (*)()) 0
表示它正在定义(函数)指针,并且指针的值为0
。
同样,SIG_DFL
是一个值为2
的常量,其类型为void(*)(int)
,是(函数)指针。
对于函数指针,可以直接调用它。
#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)
}
为什么上面三件事的定义是
void (*)()
?
因为这就是signal
函数所需要的。 signal
函数要求其处理函数具有void (*)(int)
之类的函数签名。
因此,伪函数(SIG_DFL
,SIG_IGN
)也必须是void (*)(int)
类型。
请注意SIG_ERR
用于指示处理程序设置失败。
请参见https://en.cppreference.com/w/c/program/signal中的 handler 的参数说明。
定义中的数字-1 0 1是什么意思?
请参见What 's the meaning of the number 1 in SIG_IGN macro definition?
我不得不说起初我主要被困在模式#define SIG_DFL (void (*)()) 0
中,但我没有意识到这是强制转换。.:)