SIG_IGN,SIG_DFL,SIG_ERR的定义

时间:2016-03-06 15:05:39

标签: c linux signals

<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是什么意思?

我如何解释这些定义?

2 个答案:

答案 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_DFLSIG_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中,但我没有意识到这是强制转换。.:)