将整数转换为信号代码中的函数指针 - 为什么这样做?

时间:2011-12-07 17:12:01

标签: c++ c unix

我正在读一本书(UNIX环境下的高级编程),我正在阅读有关信号的部分。

使用信号功能时:

void (*signal(int signo, void (*func)(int)))(int);

参数func可以是指向用户定义的函数的指针,也可以是SIG_ERR,SIG_DFL或SIG_IGN。

我的问题不在UNIX的部分,但我想提供背景知识。我真正想知道的是,这本书指出这些常数是不确定的:

#define SIG_ERR (void (*)())-1

等为0和1。

现在,我有一些不错的猜测,但为了节省时间 - 有人能告诉我这是做什么以及为什么有效?

另外,有......呃...更干净?假设我正在使用C ++并与此C API交互,那么写这个的方法呢?

3 个答案:

答案 0 :(得分:11)

它正在向函数指针强制转换整数; * 可能会选择占位符值,以便它们永远不会与实际函数指针的值发生冲突。然后,signal的实现可能会检查这些特殊值的输入参数。

<小时/> * C标准允许这样做(见6.3.2.3第5页),尽管它说结果是实现定义的。显然,操作系统的作者能够控制实现定义的方面,所以一切都没问题。

答案 1 :(得分:2)

#define SIG_ERR (void (*)())-1

这会将-1转换为指向函数的指针(即不带任何内容并且不返回任何内容的函数)。这会使SIG_ERR始终无效且与NULL不同。

答案 2 :(得分:2)

好吧,它确实将SIG_ERR定义为一个指向void函数的指针,该函数接受地址为-1的任意数量的参数。 SIG_DFL的地址为0,SIG_IGN的地址为1.这些只是原始信号处理函数的特殊值,这些地址可能是您不应该关注的实现细节。只需使用为您定义的宏,您就会很好。

如果你想要它更清洁 - 声明你自己的函数,例如什么都不做的函数并忽略信号,并使用指针代替SIG_IGN ......

但我怀疑在C ++代码中包装信号处理有什么价值。出于某种原因,C ++程序员喜欢把所有东西都包装好,甚至包括这个简单直接的C API。