Path: utzoo!attcan!uunet!convex!killer!ames!think!bloom-beacon!mcgill-vision!mouse
From: mouse@mcgill-vision.UUCP (der Mouse)
Newsgroups: comp.unix.questions
Subject: Re: Casting function ptrs
Message-ID: <1124@mcgill-vision.UUCP>
Date: 30 May 88 03:36:11 GMT
References: <280@marob.MASA.COM> <127@pigs.UUCP>
Organization: McGill University, Montreal
Lines: 66
Posted: Sun May 29 23:36:11 1988

In article <127@pigs.UUCP>, haugj@pigs.UUCP (John F. Haugh II) writes:
> In article <280@marob.MASA.COM>, daveh@marob.MASA.COM (Dave Hammond) writes:
>> Given a list of varying typed functions, their names and addresses:
>> struct funcs { char *name; unsigned (*func)(); };
>> char *foo();
>> struct funcs f = {  "foo", (char *)foo };
> the field `func' is `pointer to function returning unsigned'.
> assigning anything else to it, such as a pointer to a function
> returning a pointer to a character, as you do in the example above,
> is wrong.

Except that what he's assigning is not a pointer to function at all,
but a pointer to char (as per the cast).  Try

struct funcs f = { "foo", (unsigned (*)())foo };

>> And a routine which is passed a function name in order to lookup and
>> return its associated address:
>> unsigned *lookup_func(name) char *name;
>> { .... return( (unsigned *) f->func ); }
> this is also incorrect.  lookup_func should have its return value the
> same type as f->func.

Yes.

> the correct declaraction for lookup_func is
> unsigned *(*lookup_func()) (name) char *name; { ... }

This declares lookup_func as a function with no arguments returning a
pointer to a function returning pointer to unsigned.  The "char *name"
will provoke an error message about an argument declared but not
mentioned in the argument list.  The place you have name is the
argument list for the *return value*, not for lookup_func itself; this
will likely provoke another error message unless your compiler accepts
ANSI-style prototype argument lists (and possibly then; I'm not certain
whether the above is legal ANSI, or rather would be if the "char *name"
were deleted).

Try

unsigned (*lookup_func(name))()
char *name;
{
 unsigned (*retp)();
 ...
 return(retp);
}

If your compiler accepts ANSI-style prototype argument lists, you can
put stuff in the other pairs of parentheses to declare the arguments to
the return value:

unsigned (*lookup_func(char *name))(int,int,long)
/* for example.  Returned function takes three args: int, int, and long. */
{
 unsigned (*retp)(int,int,long);
 ....
 retp = (unsigned (*)(int,int,long)) ....;
 ....
 return(retp);
}

					der Mouse

			uucp: mouse@mcgill-vision.uucp
			arpa: mouse@larry.mcrcim.mcgill.edu