Thursday, November 4, 2010

Question 1.22

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 (sugested 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.)

No comments:

Post a Comment