[net.lang.c] ANSI C and function prototypes

steve@harvard.UUCP ( Pratap) (02/04/86)

	Here is a short question regarding the new ANSI standard and 
function prototypes.

	Let's say I want to write a 'dispatcher' routine that is 
passed a code number and a pointer to a function to call.
I wish to use a prototype to make sure that I am always passing 
two arguments, the first of which is an int and the 
second of which is a function pointer.  
	I might define the prototype as:

	dispatcher(int code, void (*disp_func)());

	My problem is that under the standard it will always be an error to 
call this routine with a pointer to a function that does NOT return void.

	Is there any way to prototype the second argument as a pointer to
a function returning 'anything'?  I realize if I prototype the second
argument as a 'void *pointer', any pointer will be properly converted, 
but this defeats my purpose of checking to make sure that the second
argument is really a function pointer.

	I can think of many times when I have passed pointers to functions 
that return various different types, yet I see no way of doing this when
using prototypes.  

		Steve Kaufer
		steve@harvard.HARVARD.EDU
		{seismo,ihnp4,allegra,ut-sally}!harvard!steve

henry@utzoo.UUCP (Henry Spencer) (02/07/86)

>   ...Is there any way to prototype the second argument as a pointer to
> a function returning 'anything'?  I realize if I prototype the second
> argument as a 'void *pointer', any pointer will be properly converted, 
> but this defeats my purpose of checking to make sure that the second
> argument is really a function pointer...

Prototyping it as "void *" is wrong too, and a strict ANSI-compliant
compiler will reject use of it as illegal.  "void *" is a generic *data*
pointer, and function pointers are not data pointers.  The ANSI drafts
say that mixing function pointers and data pointers is illegal, period,
although it is listed in the relevant appendix as a "common extension".
It certainly is a potential portability problem even if the compiler
permits it.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

jsdy@hadron.UUCP (Joseph S. D. Yao) (02/11/86)

In article <681@harvard.UUCP> steve@harvard.UUCP (Kaufer - Lopez - Pratap) writes:
>	Let's say I want to write a 'dispatcher' routine that is 
>passed a code number and a pointer to a function to call.
>I wish to use a prototype to make sure that I am always passing 
>two arguments, the first of which is an int and the 
>second of which is a function pointer.  
>	I might define the prototype as:
>	dispatcher(int code, void (*disp_func)());
>	Is there any way to prototype the second argument as a pointer to
>a function returning 'anything'?

If 'anything' is limited to pointers, you can say:
	int dispatcher(int code, void *(*disp_func)());
as I understand it.  (If you are going to explicitly declare the
arguments to your functions, then by all means declare the
function itself!!)  Otherwise, if you want to include scalars
and structures, you must build a union and have the prototype
return that.  Of course, since no one but EcoSoft (tentative as
that is) has prototyping, there's no compiler to check this
against.  (I don't have EcoSoft C.)
-- 

	Joe Yao		hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}

gnu@hoptoad.uucp (John Gilmore) (02/13/86)

In article <250@hadron.UUCP>, jsdy@hadron.UUCP (Joseph S. D. Yao) writes:
> In article <681@harvard.UUCP> steve@harvard.UUCP (Kaufer - Lopez - Pratap) writes:
> >	Let's say I want to write a 'dispatcher' routine that is 
> >passed a code number and a pointer to a function to call.
> >I wish to use a prototype to make sure that I am always passing 
> >two arguments, the first of which is an int and the 
> >second of which is a function pointer.  
> >	I might define the prototype as:
> >	dispatcher(int code, void (*disp_func)());
> >	Is there any way to prototype the second argument as a pointer to
> >a function returning 'anything'?
> 
> If 'anything' is limited to pointers, you can say:
> 	int dispatcher(int code, void *(*disp_func)());
> as I understand it.

Not true.  When you declare the return type of a function (or function
pointer), what you say has to agree with what it does.  This is not a
type-cast, it's a declaration, folks -- if you declare "int foo" in one
file you'd better not call it "float foo" in another.  You can't cast a
"function returning int" into a "function returning void *".  You CAN
cast its *result* after it has returned, but you can't cast the *function*.

It matters because compilers may need to allocate stack or register
space for the result of calling thru the function pointer.  Depending
on the type of the result (of the actual function called), more or less
space might need to be allocated by the caller.  I can think of good
reasons for having different return conventions for each of these
different return types: struct, int, long, int *, char * or void *.
Consider a sufficiently odd machine (word addressed, 16 bit words,
separate address&data regs).  If you call a function that doesn't match
your function pointer declaration, the registers or stack can get
clobberred.  Definitely nonportable.

The only safe bet is to make sure that all the functions which will be
called through this function pointer *do indeed* return the type you
declared the pointer with.
-- 
John Gilmore  {sun,ptsfa,lll-crg,ihnp4}!hoptoad!gnu   jgilmore@lll-crg.arpa

rich@rexago1.UUCP (K. Richard Magill) (02/13/86)

In article <250@hadron.UUCP> jsdy@hadron.UUCP (Joseph S. D. Yao) writes:
>Of course, since no one but EcoSoft (tentative as
>that is) has prototyping...
Doesn't Datalight also have prototyping?

K. Richard Magill

cg@myrias.UUCP (Chris Gray) (02/13/86)

-------
Input C program:
-------
dispatcher(int code, void (*disp_func)());
-------
Output from compiler with symbol table dump debugging flag turned on:
-------
dispatcher: function - function (signed int, pointer to function () returning void) returning signed int
-------
(Sorry for the long output line - you should see them for some of the things
I tested it with!)

As for what this means under the draft ANSI spec, well.......

jimc@ucla-cs.UUCP (02/14/86)

In article <250@hadron.UUCP> jsdy@hadron.UUCP (Joseph S. D. Yao) writes:
>return that.  Of course, since no one but EcoSoft (tentative as
>that is) has prototyping, there's no compiler to check this
>against.  (I don't have EcoSoft C.)
>--
IBM "C" ((c) Microsoft) for the PC claims to attempt to conform to what the
ANSI spec will eventually evolve to.  In particular, it includes function
prototypes.

James F. Carter            (213) 206-1306
UCLA-SEASnet; 2567 Boelter Hall; 405 Hilgard Ave.; Los Angeles, CA 90024
UUCP:...!{ihnp4,ucbvax,{hao!cepu}}!ucla-cs!jimc  ARPA:jimc@locus.UCLA.EDU