22

I'd like to declare a function that returns a pointer to a function of the same type.

I would like to use it to implement state machines like the one below:

typedef event_handler_t (*event_handler_t)(event_t*); // compilation error

event_handler_t state2(event_t* e);
event_handler_t state1(event_t* e) {
    switch(e->type) {
    //...
    case SOME_EVENT:
        return state2;
    //...
    }

}
event_handler_t state2(event_t* e) {
    switch(e->type) {
    //...
    case OTHER_EVENT:
        return state1;
    //...
    }   
}

//...
event_handler_t event_handler;
//...
event_handler(&e);
//...

I manage to work around the compliation error using structures as follows:

typedef struct event_handler {
    struct event_handler (*func)(event_t *);
} event_handler_t;

But this makes return statment more complicated:

event_handler_t state2(event_t* e) {
{
    event_handler_t next_handler = {NULL};
    switch(e->type) {
    //...
    case OTHER_EVENT:
        next_handler.func = state1;
        break;
    //...
    } 
    return next_handler;
}

I wonder if there is a better way to create such function pointers in c.

Piotr Czapla
  • 25,734
  • 24
  • 99
  • 122
  • 1
    See also: [SO 816356](http://stackoverflow.com/questions/816356/how-can-i-typedef-a-function-pointer-that-takes-a-function-of-its-own-type-as-an) – Jonathan Leffler Oct 13 '13 at 20:43

2 Answers2

8

It's not possible to do this in C: a function can't return a pointer to itself, since the type declaration expands recursively and never ends. See this page for an explanation: http://www.gotw.ca/gotw/057.htm

The workaround described on the above page means returning void (*) () instead of the correctly-typed function pointer; your workaround is arguably a little neater.

Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
2

This is discussed in Herb Sutter's book More Exceptional C++, Item 32, where the answer seems to be (for C) "not without use of casts". For C++ it is possible with the usual introduction of a class to provide some extra indirection.

sth
  • 222,467
  • 53
  • 283
  • 367