我正在读一本书(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交互,那么写这个的方法呢?
答案 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。