联系
Knight's Tale » 技术

APUE书本中关于SIG_ERR的定义

2011-02-22 22:13

在《UNIX高级环境编程》(第二版)第241页中,有关于signal 与 SIG_ERR的定义:

void (*signal   (int signo, void (*func)(int))  )(int);
#define SIG_ERR (void (*)()) -1

在程序清单10-1中,有这么一行代码:

if(signal(SIGUSER1, sig_usr) == SIG_ERR)

看到上面三行代码后,看书认真的同学肯定有疑问,SIG_ERR的定义不对啊,SIG_ERR应该要有参数才对,SIG_ERR的定义应该:

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

才对啊!

为此,我分别在VS2010与VIM环境下简单的写了几行代码来验证SIG_ERR是否有误。结果发现:

  • VS2011要求SIG_ERR的定义中,函数必须要有参数,否则编译不让通过
  • VIM则认为书上SIG_ERR定义是正确的,编译运行通过,即便函数声明不严谨(没有参数)。文献[1]给出了一个解释:“老版本的c无参表示可以有任意参数”。我想这个解释是正确的。

附验证程序:

void (*signalTest    (int signo, void (*func)(int)) )(int)
{
    return NULL;
}

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

void main()
{
    if(signalTest(0,NULL)==SIG_ERR_TEST)
        return;
}

这个程序在VS2010下编译通不过,但是在VIM下编译通过了。 并且,当我把验证程序改成: (修改了signalTest的参数)

void (*signalTest    (int signo, void (*func)(int)) )(int,int )
{
    return NULL;
}

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

void main()
{
    if(signalTest(0,NULL)==SIG_ERR_TEST)
        return;
}

这个程序在VIM还是可以编译通过了。由此可见,文献[1]的解释是合理的。

附注:

Linux(Ubuntu10.04)环境下SIG_ERR的定义:
#typedef void (*__sighandler_t) (int);
#define SIG_ERR ((__sighandler_t) -1)       /* Error return.  */

Reference:

  1. http://topic.csdn.net/u/20090503/13/7cd57cbd-833b-4023-abb4-f9a51dc32832.html