1
#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什么?

4

2 回答 2

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 没有提到这些常量-10或者1,宁愿只说符号常量(无论如何,在预期的地方)<signal.h>:.

进一步阅读:

于 2016-01-30T18:33:18.367 回答
1

为已接受的答案添加有用的参考资料。

来自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该信号表明进程进行了无效的内存引用(这通常表明程序存在错误,例如取消引用未初始化的指针)。

于 2019-03-28T06:25:58.067 回答