#define SIG_IGN (void (*)(int))1
#define SIG_HOLD (void (*)(int))5
#define SIG_ERR ((void (*)(int))-1)
我知道(void (*)(int))
的含义:将unknown_name转换为指向函数(int)的指针返回void。
但是以下1
的含义是什么?
答案 0 :(得分:3)
使用常量,以便可以将其与有效的函数指针区分开来。它本身没有任何意义(除了区别)。
例如:
#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>
。
进一步阅读:
答案 1 :(得分:1)
添加关于接受答案的有用参考资料。
来自 APUE :
如果我们检查系统标题,我们可能会发现 形式的声明
#define SIG_ERR (void (*)()) -1 #define SIG_DFL (void (*)()) 0 #define SIG_IGN (void (*)()) 1
这些常量可以代替“指向函数的指针” 它接受一个整数参数,但不返回任何内容,’’第二个
signal
的参数,以及signal
的返回值。 三个 用于这些常数的值不必为-1、0和1。它们必须为 三个值,它们永远不能是任何可声明函数的地址。 大多数UNIX系统使用显示的值。
是的,它可以确保您在尝试做愚蠢的事情like me时会出错(也许我不知道其他(有用/愚蠢的)事情):
#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
此信号表示该进程已无效 内存引用(通常表明程序存在错误, 例如取消引用未初始化的指针。