🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #124

Re: Function Prototypes: Don't they force casts?

#124
From: Chris Torek
Date: Sun, 26 Jul 1992 21:06
79 lines
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!torek
References: <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