home *** CD-ROM | disk | FTP | other *** search
- Path: 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
-
- 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
-