guido@cwi.nl (Guido van Rossum) (03/26/91)
I have some code that uses signal(). Nothing spectacular, e.g.: #include <signal.h> ... void (*sigsave)(); sigsave = signal(SIGINT, SIG_IGN); ... signal(SIGINT, sigsave); The compiler that comes closest to Standard C locally (gcc) warns about this code: sigsave = signal(SIGINT, SIG_IGN); warning: argument passing between incompatible pointer types signal(SIGINT, sigsave); warning: assignment between incompatible pointer types I don't see what's wrong. I noticed that the declaration for signal() in <signal.h> looks as follows: extern void (*signal(int, void (*) (int, ...)))(int, ...); Is the header wrong, is gcc overly worried, or is my code wrong? --Guido van Rossum, CWI, Amsterdam <guido@cwi.nl> "What do you *mean* it's not in the computer!" -- Madonna
diamond@jit345.swstokyo.dec.com (Norman Diamond) (03/27/91)
In article <3223@charon.cwi.nl> guido@cwi.nl (Guido van Rossum) writes: >... the declaration for signal() in <signal.h> looks as follows: > extern void (*signal(int, void (*) (int, ...)))(int, ...); >[gcc complains about:] > #include <signal.h> > void (*sigsave)(); You did not declare void (*sigsave)(int, ...); > sigsave = signal(SIGINT, SIG_IGN); > warning: argument passing between incompatible pointer types What is the definition of SIG_IGN in your machine's <signal.h> ? > signal(SIGINT, sigsave); > warning: assignment between incompatible pointer types Because your sigsave must point to a non-varargs function. >Is the header wrong, is gcc overly worried, or is my code wrong? Maybe (SIG_IGN?) , Maybe / Maybe not , AND yes >--Guido van Rossum, CWI, Amsterdam <guido@cwi.nl> >"What do you *mean* it's not in the computer!" -- Madonna It's in the soft ware. -- Norman Diamond diamond@tkov50.enet.dec.com If this were the company's opinion, I wouldn't be allowed to post it.
guido@cwi.nl (Guido van Rossum) (03/27/91)
In article <3223@charon.cwi.nl> I asked: >>... the declaration for signal() in <signal.h> looks as follows: >> extern void (*signal(int, void (*) (int, ...)))(int, ...); >> >>[gcc complains about:] >> #include <signal.h> >> void (*sigsave)(); >> ... >> signal(SIGINT, sigsave); Norman Diamond replies: >You did not declare void (*sigsave)(int, ...); Indeed, but I believe my code conforms to the Standard: 4.7.1.1 lists the second argument of signal() as void (*func)(int), not as void (*func)(int, ...). I thought varargs (sorry, stdarg) functions *had* to be declared with prototypes, while for functions with fixed argument lists, old style declarations were also acceptable. Therefore I believe my declaration is compatible with the standard, while the <signal.h> in question (provided by SGI) is not. Any other opinions? --Guido van Rossum, CWI, Amsterdam <guido@cwi.nl> "The life of a Repo Man is always intense"
karl@ima.isc.com (Karl Heuer) (03/28/91)
In article <3223@charon.cwi.nl> guido@cwi.nl (Guido van Rossum) writes: >Is the header wrong, is gcc overly worried, or is my code wrong? All of the above. The header is wrong, because the Standard specifies that signal handlers take a single arg of type |int|; the BSDism of pretending they're variadic is not compatible with existing practice. (Recommended fix: make your own copy of <signal.h> that adheres to the standard. See enclosure.) GCC is overly worried, but it did restrict it to a warning (rather than a fatal error), which is appropriate behavior for a compiler when presented with improper but fixable code. Your code is wrong because it uses the obsolescent |void (*sigsave)()| rather than the prototype |void (*sigsave)(int)|. This should not cause any problems, though, unless you're using the -Wstrict-prototypes option. Karl W. Z. Heuer (karl@ima.isc.com or uunet!ima!karl), The Walking Lint --------cut here-------- /* * Karl Heuer, 27-Mar-1991. Public Domain. * * For systems whose native <signal.h> is not ANSI-compatible. Imports most * stuff from the native <signal.h>, which we assume to be in /usr/include * (but we spell it with a double slash because some compilers warn about * including from /usr/include explicitly). The second paragraph can begin * with either an include of <whoami.h>, which is expected to define * appropriate symbols in the _[SMCX]_* namespace, or the defines can be * inlined at this point. */ #if !defined(_H_SIGNAL) /* some implementations misdeclare signal() */ #define signal __dummy_signal #define sigvec __dummy_sigvec #include "/usr//include/signal.h" #undef signal #undef sigvec #define _H_SIGNAL #include <whoami.h> #if defined(_S_UNIX_BSD) || defined(_X_HAS_SIGVEC) struct sigvec { #if defined(__STDC__) void (*sv_handler)(int); #else void (*sv_handler)(); #endif int sv_mask; int sv_flags; }; #if defined(__STDC__) extern int sigvec(int, struct sigvec const *, struct sigvec *); #else extern int sigvec(); #endif #endif /* BSD mutation */ #undef SIG_DFL #undef SIG_IGN #undef SIG_ERR #if defined(__STDC__) #if defined(lint) #define SIG_DFL ((void (*)(int))0) #define SIG_IGN ((void (*)(int))0) #define SIG_ERR ((void (*)(int))0) #else #define SIG_DFL ((void (*)(int))0) #define SIG_IGN ((void (*)(int))1) #define SIG_ERR ((void (*)(int))-1) #endif extern void (*signal(int, void (*)(int)))(int); extern int raise(int); #else #if defined(lint) #define SIG_DFL ((void (*)())0) #define SIG_IGN ((void (*)())0) #define SIG_ERR ((void (*)())0) #else #define SIG_DFL ((void (*)())0) #define SIG_IGN ((void (*)())1) #define SIG_ERR ((void (*)())-1) #endif extern void (*signal())(); extern int raise(); #endif #if !defined(SIGABRT) #define SIGABRT SIGIOT #endif #endif /* include guard */
gwyn@smoke.brl.mil (Doug Gwyn) (03/28/91)
In article <3223@charon.cwi.nl> guido@cwi.nl (Guido van Rossum) writes: >I don't see what's wrong. I noticed that the declaration for signal() >in <signal.h> looks as follows: > extern void (*signal(int, void (*) (int, ...)))(int, ...); The header is wrong (i.e. not part of a conforming implementation). The signal handler function does NOT have a variable argument list, but always receives precisely one argument of type int. The ,... is a bogus attempt to accommodate 4.2BSD-style signal handers. If some recent modification has been made to POSIX.1 that requires this, it is WRONG and in general incompatible with the C standard. (This issue was carefully discussed at both X3J11 and P1003 levels before the original standards were adopted.)
torek@elf.ee.lbl.gov (Chris Torek) (03/29/91)
In article <15605@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >The signal handler function does NOT have a variable argument list, >but always receives precisely one argument of type int. The ,... is >a bogus attempt to accommodate 4.2BSD-style signal handers. If some >recent modification has been made to POSIX.1 that requires this, it >is WRONG and in general incompatible with the C standard. The word on the streets is that current POSIX drafts *do* require more than one argument. It was probably a mistake for ANSI X3.159-1989 and POSIX to attempt to share the name `signal' and the type `signal handler' at all. -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov
mbrown@testsys.austin.ibm.com (Mark Brown) (03/29/91)
torek@elf.ee.lbl.gov (Chris Torek) writes: |gwyn@smoke.brl.mil (Doug Gwyn) writes: |>The signal handler function does NOT have a variable argument list, |>but always receives precisely one argument of type int. The ,... is |>a bogus attempt to accommodate 4.2BSD-style signal handers. If some |>recent modification has been made to POSIX.1 that requires this, it |>is WRONG and in general incompatible with the C standard. | |The word on the streets is that current POSIX drafts *do* require more |than one argument. POSIX 1003.1-1990 (the ISO version), Section 3.3.1.3 Signal Actions, Sub 3b - "The signal-catching function shall be entered as a C language function call as follows: void func ( int SIGNO ); where func is the specified signal-catching function and SIGNO is the signal number of the signal being delivered." [This is the OFFICIAL POSIX DOCUMENT for .1, not a draft.] POSIX 1003.2 Draft 11 (the current draft) says nothing. POSIX 1003.2a Draft 6 says nothing. I can't speak for the .4 folks, or the multiprocessing people. I can say that every effort is made to keep from contradicting the C standard.... -- Mark Brown IBM PSP Austin, TX. (512) 823-3741 VNET: MBROWN@AUSVMQ MAIL: mbrown@testsys.austin.ibm.com OR uunet!testsys.austin.ibm.com!mbrown The nice thing about standards is that there are so many to choose from! DISCLAIMER: Any personal opinions stated here are just that.
gwyn@smoke.brl.mil (Doug Gwyn) (03/29/91)
In article <11568@dog.ee.lbl.gov> torek@elf.ee.lbl.gov (Chris Torek) writes: >The word on the streets is that current POSIX drafts *do* require more >than one argument. Then SC22 or whatever the appropriate coordinating agency is should block the conflicting standard. >It was probably a mistake for ANSI X3.159-1989 and POSIX to attempt >to share the name `signal' and the type `signal handler' at all. POSIX.1 deliberately relegated signal() to a different category from sigvec(). I don't much care how sigvec() handlers are specified, but signal() handlers MUST conform to the previously-decided interface.
diamond@jit345.swstokyo.dec.com (Norman Diamond) (03/29/91)
In article <3228@charon.cwi.nl> guido@cwi.nl (Guido van Rossum) writes: >Therefore I believe my declaration is compatible with the standard, It was; though the combination of your declaration with the contents of your <signal.h> (which was not provided by your processor, gcc) yielded an invalid program. >while the <signal.h> in question (provided by SGI) is not. Essentially true. The <signal.h> that was provided to you by SGI cannot really be part of a standard-conforming implementation. (Wierd hacks could be made to the compiler in order to get around this, but it's not worth worrying about.) >Any other opinions? If you want a standard-conforming processor, you should install a complete standard-conforming processor, not just half of one. -- Norman Diamond diamond@tkov50.enet.dec.com If this were the company's opinion, I wouldn't be allowed to post it.
gwyn@smoke.brl.mil (Doug Gwyn) (03/30/91)
In article <1991Mar29.065157.609@tkou02.enet.dec.com> diamond@jit345.enet@tkou02.enet.dec.com (Norman Diamond) writes: >The <signal.h> that was provided to you by SGI >cannot really be part of a standard-conforming implementation. Yes, I in fact received e-mail from a compiler implementor at SGI promising that this would be fixed in a forthcoming release of a standard-conforming implementation. (SGI's current release fails to conform fully to the C standard in several ways, presumably all to be fixed in the aforementioned forthcoming release.)