[comp.sys.hp] HP-UX type declaration problem with signal

rrs@bnrunix.UUCP (Randall Stewart) (06/23/89)

saves the old signal handler and then set's a signal handler and of
course at a later time restores the original signal handler...
********************************************************************
#include <signal.h>
        
int (*old)(),newhand();

old = signal(SIGINT,newhand);
..
...code of module
..
signal(SIGINT,old);

When compiling on a 6.2 machine I had no problems but when I compile on
a 6.5 machine. I get "line xxxx: warning: incorrect pointer combination"

upon looking at <signal.h> and comparing the 6.2 vs: the 6.5, I find this
difference...

6.2---
extern  (*signal())();


6.5---
extern  void (*signal())();
******************************************************
Should not 6.5 have a statement more like 6.2?????

Or to be real picky I would prefer:

extern int (*signal())();

---------
Being the paranoid type I even wrote a small test program to make sure
that the 6.5 signal call still returns the old function pointer.
It worked as expected and I did get a return of a function
pointer from signal.

What do y'all think?

Randall

rer@hpfcdc.HP.COM (Rob Robason) (06/27/89)

> upon looking at <signal.h> and comparing the 6.2 vs:  the 6.5, I find
> this difference...

> 6.2---
> extern  (*signal())();
> 6.5---
> extern  void (*signal())();
> 
> Should not 6.5 have a statement more like 6.2?????

This is a result of the support of ANSI C, which redefines the return
value of signal to be a pointer to void, which is an ANSICism for a
"generic" pointer.

From the standard:

A pointer to void shall have the same representation and alignment
requirements as a pointer to a character type.

From the ANSI C Rationale:

A "pointer to void," void *, is a generic pointer, capable of pointing
to any (data) object without trunctation.

> Randall
> ----------

Rob Robason

rml@hpfcdc.HP.COM (Bob Lenk) (06/29/89)

> 6.2---
> extern  (*signal())();
> 6.5---
> extern  void (*signal())();
> 
> Should not 6.5 have a statement more like 6.2?????

The only difference is between the declarations is whether the signal
handler returns an integer or returns no value.  Throughout UN*X
history, signal handlers have never actually returned a value (or if
they did it was discarded).  However, the original C language did not
support declarations of functions that did not return a value, but more
recent versions support the type void for this purpose.  Thus the newer
declaration is technically more correct.  The only change this requires
in user is changing from declarations from (possibly implicit) int to
void.  Depending on the specifics, failures to do this may generate
compiler warnings, compiler errors, or neither.  Any code that compiles
will run without problem (as will existing binaries).

The reason that HP-UX changed the declaration of signal() in 6.5 is to
conform to the SVID (System V Interface Definition) Base System
Definition Addendum, published in 1986 as Volume III of Issue 2 of the
SVID.  The previous SVID, to which 6.2 conformed, specified the int
declaration.

As a previous response alludes, the (proposed) ANSI C Standard specifies
the void type, and specifies signal() with this declaration.  Although,
6.5 does not conform to this standard, these changes are consistent with
moving toward it.

This change should probably have been mentioned in the Update_info file,
but was not.

		Bob Lenk (rml@hpfcla)

ross@ziebmef.uucp (Ross Ridge) (07/08/89)

In article <5570224@hpfcdc.HP.COM> rer@hpfcdc.HP.COM (Rob Robason) writes:
>> upon looking at <signal.h> and comparing the 6.2 vs:  the 6.5, I find
>> this difference...
>
>> 6.2---
>> extern  (*signal())();
>> 6.5---
>> extern  void (*signal())();
>> 
>> Should not 6.5 have a statement more like 6.2?????
>
>This is a result of the support of ANSI C, which redefines the return
>value of signal to be a pointer to void, which is an ANSICism for a
>"generic" pointer.

This is not correct. ANSI C (and newer Sys V releases) defines signal
as returning a pointer to a function returning void (nothing). This
is not the "generic" pointer to void (void *). 

The old way to use signal was like this:

{
	int (*old_handler)();
	int int_handler();

	old_hanlder = signal(SIGINT, int_handler);
}

The new way is:

{
	void (*old_handler)(/* int */);
	void int_handler(/* int */);

	old_handler = signal(SIGINT, int_handler);
}

That's all that has changed. If you're worried about compability do something
like:

#ifdef NEW_SIGNAL

typedef signal_type void

#else

typdef signal_type int

#endif

								Ross Ridge
-- 
 l/                   attcan!tmsoft!ziebmef!ross			 //
[OO]                   					                [oo]
-()-                                                                    -()-
 db                     6502 assembly forever!                           //