prev up next   top/contents search

comp.lang.c FAQ list · Question 1.22

Q: How can I declare a function that can return a pointer to a function of the same type? I'm building a state machine with one function for each state, each of which returns a pointer to the function for the next state. But I can't find a way to declare the functions--I seem to need a function returning a pointer to a function returning a pointer to a function returning a pointer to a function..., ad infinitum.


A: You can't quite do it directly. One way is to have the function return a generic function pointer (see question 4.13), with some judicious casts to adjust the types as the pointers are passed around:

typedef int (*funcptr)();	  /* generic function pointer */
typedef funcptr (*ptrfuncptr)();  /* ptr to fcn returning g.f.p. */

funcptr start(), stop();
funcptr state1(), state2(), state3();

void statemachine()
{
	ptrfuncptr state = start;

	while(state != stop)
		state = (ptrfuncptr)(*state)();
}

funcptr start()
{
	return (funcptr)state1;
}
(The second ptrfuncptr typedef hides some particularly dark syntax; without it, the state variable would have to be declared as funcptr (*state)() and the call would contain a bewildering cast of the form (funcptr (*)())(*state)().)

Another way (suggested by Paul Eggert, Eugene Ressler, Chris Volpe, and perhaps others) is to have each function return a structure containing only a pointer to a function returning that structure:

struct functhunk {
	struct functhunk (*func)();
};

struct functhunk start(), stop();
struct functhunk state1(), state2(), state3();

void statemachine()
{
	struct functhunk state = {start};

	while(state.func != stop)
		state = (*state.func)();
}

struct functhunk start()
{
	struct functhunk ret;
	ret.func = state1;
	return ret;
}
(Note that these examples use the older, explicit style of calling via function pointers; see question 4.12. See also question 1.17.)


prev up next   contents search
about this FAQ list   about eskimo   search   feedback   copyright

Hosted by Eskimo North