atc@ut-sally.UUCP (Alvin T. Campbell III) (06/17/87)
I have a question for all you C wizards out there. I want to write a function which returns a pointer to another function. I checked Kernighan & Ritchie and Harbison & Steele, but found no solution. My specific application is that I am writing a program which uses menus. Each menu item has an associated function which should be called when that item is selected. I want to write a function which puts a menu on the screen, lets the user select an item, and then returns the appropriate function. I want to structure the code as follows: #define TRUE 1 main() { int (*func)(); while(TRUE) { func = getmenu(); (*func)(); } } So how do I declare getmenu() ? I am writing the code on a Silicon Graphics, Inc. IRIS 2400, whose flavor of UNIX is System V with Berkeley Enhancements. The vendor has a hotline for questions, so I called there first. I was referred to someone in their compiler group. He told me to just declare getmenu() as an integer function, since it would work in this case. I am a purist, so I found this suggestion disgusting. By the way, please don't suggest that I restructure my code to avoid the problem. I know there are many ways to do this, and in fact I have done so already. I am just curious to see how to do it right. Thanks for the help. A. T. Campbell University of Texas at Austin Computer Graphics Lab atc@sally.CS.UTEXAS.EDU
edw@ius2.cs.cmu.edu (Eddie Wyatt) (06/18/87)
In article <8286@ut-sally.UUCP>, atc@ut-sally.UUCP (Alvin T. Campbell III) writes: > > I have a question for all you C wizards out there. I want to write > a function which returns a pointer to another function. I checked Kernighan > & Ritchie and Harbison & Steele, but found no solution. > > A. T. Campbell > University of Texas at Austin > Computer Graphics Lab > atc@sally.CS.UTEXAS.EDU Syntax is : <type> ( * <function_name> ( <parameter_list> ) ) ( ) Example definition for a function that returns a pointer to a function that returns an int : int tt(); int (*foobar(x))() int x; { printf("x = %d\n",x); return(tt); } int tt() { printf("Hello world\n"); return(1); } main() { int (*func)(); func = foobar(3); printf("func returns %d\n",func()); } -- Eddie Wyatt e-mail: edw@ius2.cs.cmu.edu
ark@alice.UUCP (06/18/87)
The problem: how to declare a function that returns a function pointer: int (*foo)(); foo = getfunc(); how to declare getfunc? Well, let's see: if we call getfunc(), dereference the result, and call that, we get an int. In other words, (*getfunc())() is an int, so we should say extern int (*getfunc())(); All clear?
jbuck@epimass.UUCP (06/18/87)
In article <8286@ut-sally.UUCP> atc@ut-sally.UUCP (Alvin T. Campbell III) writes: > > I have a question for all you C wizards out there. I want to write >a function which returns a pointer to another function. I checked Kernighan >& Ritchie and Harbison & Steele, but found no solution. Script started on Wed Jun 17 21:08:03 1987 % cdecl declare foo as function returning pointer to function returning int int (*foo())() % exit script done on Wed Jun 17 21:08:49 1987 I typed the line beginning "declare", and cdecl shows me the declaration. I believe this program is in the comp.sources.unix (formerly mod.sources) archives, available for anonymous FTP and such. -- - Joe Buck jbuck@epimass.EPI.COM {seismo,ucbvax,sun,decwrl,<smart-site>}!epimass.epi.com!jbuck Old arpa mailers: jbuck%epimass.EPI.COM@seismo.css.gov
crowl@rochester.arpa (Lawrence Crowl) (06/18/87)
In article <7001@alice.UUCP> ark@alice.UUCP writes: >The problem: how to declare a function that returns a function pointer: > >..., so we should say > > extern int (*getfunc())(); > >All clear? This is not clear. Let me propose a method for clearly coding complex declarations. I make use of the typedef facility. So, for the example above I will write: typedef int func_int() ; typedef func_int *ptr_func_int ; typedef ptr_func_int func_ptr_func_int() ; extern func_ptr_func_int getfunc ; So what does this method buy me? Well, it gives me a way to declare other complex types without consulting K&R and a couple of C wizards just to make sure the syntax is correct. For instance, how about a pointer to a function returning a pointer to an integer? typedef int *ptr_int ; typedef ptr_int func_ptr_int() ; typedef func_ptr_int *ptr_func_ptr_int ; extern ptr_func_ptr_int variable ; What have I lost? Well I have to type more. However, the typedefs need only be done once, so the true comparison is between: extern int (*getfunc())() ; and extern func_ptr_func_int getfunc ; I prefer the latter. -- Lawrence Crowl 716-275-5766 University of Rochester crowl@rochester.arpa Computer Science Department ...!{allegra,decvax,seismo}!rochester!crowl Rochester, New York, 14627
ka@hropus.UUCP (Kenneth Almquist) (06/18/87)
Given the code:
int (*func)();
func = getmenu();
(*func)();
Campbell wants to know how to declare getmenu. Since we want getmenu
to return an object of the same type as func, we can simply take the
the declaration of func and replace "func" with what looks like a call
to getmenu. This gives us:
int (*getmenu())();
To define getmenu, say:
int (*getmenu())() {
...
}
Reading the declaration from "inside out", we see that getmenu is
a function returning a pointer to a function returning int. Another
way to look at it is that (*getmenu())() is a C expression that
produces a result of type int.
Kenneth Almquist
bright@dataio.Data-IO.COM (Walter Bright) (06/18/87)
In article <8286@ut-sally.UUCP> atc@ut-sally.UUCP (Alvin T. Campbell III) writes:
< I have a question for all you C wizards out there. I want to write
<a function which returns a pointer to another function. I checked Kernighan
<& Ritchie and Harbison & Steele, but found no solution.
<
<main()
<{ int (*func)();
<
< func = getmenu();
< (*func)();
<}
< So how do I declare getmenu() ?
int (*getmenu())();
The trick to doing declarations like these is to notice that the syntax
for the declaration of a variable is identical to the syntax for the use
of that variable. For example, to call a function:
func();
To call a function using a pointer to a function, replace func with
*pfunc (parentheses are req'd because the trailing () binds more tightly):
(*pfunc)();
To call a function using a pointer to a function that is returned by
another function getmenu, replace pfunc with getmenu():
(*getmenu())();
and there is the declaration!
grk@sfsup.UUCP (G.R.Kuntz) (06/18/87)
In article <7001@alice.UUCP>, ark@alice.UUCP writes: : : > extern int (*getfunc())(); In the original article, the call looked like (*func)(); and the return value was not used, so it would probably better to declare getfunc as extern void (*getfunc())(); and define func as void (*func)(); Cheers, Ralph -- G. Ralph Kuntz N2HBN UUCP: {ihnp4,allegra}!attunix!grk ARPA: rutgers.rutgers.edu!pisc2b!grk PACKET: N2HBN @ NN2Z
gwyn@brl-smoke.ARPA (Doug Gwyn ) (06/19/87)
In article <8286@ut-sally.UUCP> atc@ut-sally.UUCP (Alvin T. Campbell III) writes: > int (*func)(); > func = getmenu(); > So how do I declare getmenu() ? As usual with C type declarations, all you need to do is declare the symbol in the proper context; since getmenu() has type equivalent to func, simply plug getmenu() in place of func in the declaration used for func: int (*getmenu())(); This is similar to the C library signal() function (which has void basic type instead of int). Since your example didn't use the int supposedly returned by (*func)(), perhaps you too should be using void not int.
gwyn@brl-smoke.UUCP (06/19/87)
In article <364@sol.ARPA> crowl@rochester.UUCP (Lawrence Crowl) writes: > extern func_ptr_func_int getfunc ; The problem with this is that anyone reading your code would have to untangle the several levels of typedef in order to determine the meaning of this declaration, whereas with extern int (*getfunc())(); the meaning of the declaration is patent. This is not a particularly complicated construct; anyone who has to read C code should learn how type specification works in C, after which this is easy to understand.
stevesu@copper.UUCP (06/19/87)
In article <8286@ut-sally.UUCP>, atc@ut-sally.UUCP (Alvin T. Campbell III) writes: > I have a question for all you C wizards out there. I want to write > a function which returns a pointer to another function. Ahh, this brings back fond memories of the first article I ever posted to the net, which asked a related question (couched for some odd reason in King James English). The best way to declare a function returning a pointer to a function returning an int is to use a typedef: typedef int (*PFI)(); PFI function(); This has several advantages: it's much easier to understand, it makes it much easier to figure out which set of parentheses the function's arguments go in (this was my problem three years ago), and if you like to keep the name of the function at the left margin, you don't end up with unbalanced parentheses on the previous line. Compare PFI getroutine(name, table) {...} with int (* getroutine())(name, table) which pcc won't even compile, because the arguments actually belong in the other set of parentheses. Steve Summit stevesu@copper.tek.com
hasch@gypsy.UUCP (06/19/87)
My solution in this case would be a typedef construct. You define typedef int (*FP)(); Now FP declares a type, which is a pointer to a function that returns an int. Next declare FP getfunc(), func; I think the rest of the code can remain unchanged. Harald Schaefer Siemens RTL ... psuvax1!princeton!siemens!gypsy!hasch
drw@cullvax.UUCP (Dale Worley) (06/19/87)
atc@ut-sally.UUCP (Alvin T. Campbell III) writes: > I have a question for all you C wizards out there. I want to write > a function which returns a pointer to another function. I checked Kernighan > & Ritchie and Harbison & Steele, but found no solution. int (*(f ())) (); reading inside out: f is a function which returns a pointer to a function which returns int Though this may not be discussed explicitly in K&R or H&S, it is implied by the grammar and semantics discussed by both of them. Dale -- Dale Worley Cullinet Software ARPA: cullvax!drw@eddie.mit.edu UUCP: ...!seismo!harvard!mit-eddie!cullvax!drw If you light a match, how much mass does it convert into energy?
johnston@uiucdcsb.cs.uiuc.edu (06/19/87)
Try this: extern int (*getmenu())(); Explanation: int X (); - X is a function returning int. int (*X )(); - X is a pointer to a function returning int. int (*X())(); - X is a function returning a pointer to a function returning int. Alternative preferred by me: typedef int (*FUNC)(); /* FUNC - pointer to a function returning int */ FUNC func; extern FUNC getmenu(); - Gary Johnston Department of Computer Science University of Illinois at Urbana-Champaign 1304 West Springfield Avenue Urbana, IL 61801 Phone: (217) 333-2518 USENET: {pur-ee,convex,ihnp4}!uiucdcs!johnston ARPA: johnston@b.cs.uiuc.edu CSNET: johnston%uiuc@csnet-relay