daveh@marob.MASA.COM (Dave Hammond) (05/19/88)
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 }; 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 ); } How does one declare the lookup function, the return address variable and call the returned function, while properly casting the function return value? I'm doing it like so: unsigned *lookup_func(); unsigned *(*func)(); char *retp; if ((func = lookup_func("foo")) != (unsigned *)0) { if (( retp = (char *) (*func)() )) printf("retp=%s",retp); } Yes? No? Gonna blow up on me at some point ? Dave Hammond DSI Communications, Inc. -------------------------------- UUCP: ...!marob!daveh VOICE: (516)872-3535 USMAIL: 333 W. Merrick Rd. Valley Stream, NY 11580 --------------------------------
chris@mimsy.UUCP (Chris Torek) (05/19/88)
In article <280@marob.MASA.COM> daveh@marob.MASA.COM (Dave Hammond) asks
about variadic return-value functions and pointers thereto, a duplicate
of the same question he sent to comp.lang.c. Look there for my answer.
(Incidentally, it is considered bad form to post the same question
separately to two newsgroups. There *is* a reason for the second `s'
in `Newsgroups:'. People on the mailing-list side of the ARPA/USENET
gateways are, of course, stuck with the bad form, or a more limited
forum.)
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
haugj@pigs.UUCP (John F. Haugh II) (05/21/88)
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. > 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. the correct declaraction for lookup_func is unsigned *(*lookup_func()) (name) char *name; { ... } > How does one declare the lookup function, the return address variable and > call the returned function, while properly casting the function return value? > I'm doing it like so: > unsigned *lookup_func(); > unsigned *(*func)(); > char *retp; > > if ((func = lookup_func("foo")) != (unsigned *)0) { > if (( retp = (char *) (*func)() )) > printf("retp=%s",retp); > } the return address variable has the same type as f->func, which is `pointer to function returning pointer to unsigned', or unsigned *(*retp) (); > Yes? No? Gonna blow up on me at some point ? >-- > Dave Hammond the people at ANSI land will tell you can't go converting between different types of pointers and expecting ``reasonable'' results. so, yes, it will blow up on you at some point. i suggest you find a copy of the `cdecl' program. it can come in very handy for writing casts and function and variable declarations. it also comes in handy for writing USENET articles ;-) - john. -- The Beach Bum Big "D" Home for Wayward Hackers UUCP: ...!killer!rpp386!jfh jfh@rpp386.uucp :SMAILERS "You are in a twisty little maze of UUCP connections, all alike" -- fortune
mouse@mcgill-vision.UUCP (der Mouse) (05/30/88)
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