#define SIG_IGN (void (*)(int))1
#define SIG_HOLD (void (*)(int))5
#define SIG_ERR ((void (*)(int))-1)
我知道什么(void (*)(int))
意思:将 unknown_name 转换为指向返回 void 的函数 (int) 的指针。
但是下面的意思是1
什么?
使用该常量以便可以将其与有效的函数指针区分开来。它本身没有任何意义(除了不同)。
例如:
#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
这些常量值都不是您可以调用的有效函数地址。所以它们作为特殊值很有用,可以用来说明如何处理信号。
顺便说一句,POSIX 没有提到这些常量-1
,0
或者1
,宁愿只说符号常量(无论如何,在预期的地方)<signal.h>
:.
进一步阅读:
为已接受的答案添加有用的参考资料。
来自APUE:
如果我们检查系统的 header ,我们可能会发现表单的声明
#define SIG_ERR (void (*)()) -1 #define SIG_DFL (void (*)()) 0 #define SIG_IGN (void (*)()) 1
这些常量可以用来代替“指向接受整数参数但不返回任何内容的函数的指针”、 的第二个参数
signal
以及 的返回值signal
。用于这些常量的三个值不必是 -1、0 和 1。它们必须是永远不能成为任何可声明函数的地址的三个值。 大多数 UNIX 系统使用显示的值。
是的,它确保当您尝试做像我这样的愚蠢事情时会出错(也许是其他(有用/愚蠢)的事情,我不知道):
#include <signal.h>
#include <stdio.h>
void signal_handler(int signal)
{
printf("hahahah\n");
}
int main(void)
{
void (*f1)(int);
f1 = signal(SIGINT, signal_handler);
f1(3); //Get signal SIGSEGV and failed
//Here I am calling SIG_DFL(3).
raise(SIGINT);
}
这里调用f1(3)
等于调用SIG_DFL(3)
,每个函数都有一个地址,但SIG_DFL
(0) 不是有效的,所以我得到SIGSEGV
错误。
SIGSEGV
该信号表明进程进行了无效的内存引用(这通常表明程序存在错误,例如取消引用未初始化的指针)。