Article View: comp.std.c
Article #124Re: Function Prototypes: Don't they force casts?
From: Chris Torek
Date: Sun, 26 Jul 1992 21:06
Date: Sun, 26 Jul 1992 21:06
79 lines
3460 bytes
3460 bytes
In article <OINK.92Jul26032212@julian.newshost.uwo.ca>
oink@newshost.uwo.ca (Test Account) writes:
>#include <signal.h>
>#include "myproto.h" /* This included many prototypes, but of particular
>interest here is: void memory_fault(void); */
>[...]
> if ((int) signal(SIGSEGV, memory_fault) < 0) {
> perror("Trouble initializing SEGV routine");
> exit(-1);
> }
>Under AIX 3.2 using c89, this produces a diagnostic about incompatible types:
It certainly should!
>int and pointer (don't have the exact text handy, but I hope you get the
>idea). This occurs IFF memory_fault() is declared AFTER its use or in another
>module, if it is declared before its use there is no diagnostic.
This is wrong (by which I mean `this behavior is nonconformant').
In any case, if myproto.h includes a prototype, the function is (as
it must be) declared before its name is used. Perhaps you mean
`defined'?
>The fix is simple, ((void *) memory_fault) works fine but I THINK that
>it is unnecessary.
It is not only unnecessary, it is also wrong and should cause a
diagnostic. The type `void *' is not assignment-compatible with any
pointer-to-function type.
The subject line asks whether prototypes `force casts'. No. Prototypes
provide *assignment context* and the legality of any argument for which
there is a prototype is identical to that for an assignment to a variable
of the same type as in the prototype (section 3.3.2.2, p. 42, ll. 10--16).
Now, signal() takes, as its second argument, a value of type:
pointer to function (of one arg: int) returning void
(section 4.7.1.1). The `memory_fault' prototype says that
memory_fault is a
function (of no args) returning void
so that mentioning it produces a pointer to this. These are not
assignment-compatible (section 3.3.16.1) and this requires a diagnostic.
The diagnostic can be eliminated (at the cost of undefined runtime
behavior, i.e., without fixing the bug) with:
signal(SIGSEGV, (void (*)(int))memory_fault)
The correct fix, of course, is to change memory_fault so that it takes
exactly one `int' argument, and change the prototype correspondingly.
In any case, the test
if ((int)signal(...) < 0) ...
is quite wrong, and will fail on machines on which function pointers
appear negative after conversion to int. (I have a fuzzy memory that
suggests this may have been the case on some Elxsi machine, for
instance.) It should be
if (signal(...) == SIG_ERR) ...
If you have a pre-ANSI system that does not define SIG_ERR, this will
probably work:
#ifndef SIG_ERR
#define SIG_ERR ((void (*)(int))-1)
#endif
(The reason for using SIG_ERR in the first place is that the above is,
obviously, not portable. I claim only that it will `probably work'.)
--
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427)
Berkeley, CA Domain: torek@ee.lbl.gov
Technical Details
Message-ID:
<24914@dog.ee.lbl.gov>Path:
arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!swrinde!mips!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ucbvax!dog.ee.lbl.gov!horse.ee.lbl.gov!torekReferences:
<OINK.92Jul26032212@julian.newshost.uwo.ca>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!swrinde!mips!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ucbvax!dog.ee.lbl.gov!horse.ee.lbl.gov!torek From: torek@horse.ee.lbl.gov (Chris Torek) Newsgroups: comp.std.c Subject: Re: Function Prototypes: Don't they force casts? Message-ID: <24914@dog.ee.lbl.gov> Date: 26 Jul 92 21:06:09 GMT References: <OINK.92Jul26032212@julian.newshost.uwo.ca> Reply-To: torek@horse.ee.lbl.gov (Chris Torek) Organization: Lawrence Berkeley Laboratory, Berkeley Lines: 79 NNTP-Posting-Host: 128.3.112.15