A function cannot return a pointer to itself. A function pointer contains the return type, so in the act of returning it, you change the return type!
It's a bit like a structure which contains a copy of itself.
However, you can break the cycle by going via a void pointer, though strictly speaking casting function pointers to void* and back again is not permitted. void* can point at any data, but functions are not data.
With this in mind, you could do this
Code:
#include <stdio.h>
typedef void *(*fn)(int);
void * s1 ( int state );
void * s2 ( int state );
void * s3 ( int state );
void * s1 ( int state ) {
void * next_state = s2;
printf( "s1(%d)\n", state );
return next_state;
}
void * s2 ( int state ) {
void * next_state = s3;
printf( "s2(%d)\n", state );
return next_state;
}
void * s3 ( int state ) {
void * next_state = NULL;
printf( "s3(%d)\n", state );
return next_state;
}
int main ( ) {
fn state = s1;
while ( state != NULL ) {
state = state(123);
}
return 0;
}
For a totally "by the book" answer, extend Quzah's answer to include an enumeration. It's a bit of extra work, but the enumeration keeps things nice and readable.
Code:
#include <stdio.h>
typedef enum {
FN_S1,
FN_S2,
FN_S3,
FN_FINISH
} fn_et;
typedef fn_et (*fn)(int);
fn_et s1 ( int state );
fn_et s2 ( int state );
fn_et s3 ( int state );
fn_et s1 ( int state ) {
fn_et next_state = FN_S2;
printf( "s1(%d)\n", state );
return next_state;
}
fn_et s2 ( int state ) {
fn_et next_state = FN_S3;
printf( "s2(%d)\n", state );
return next_state;
}
fn_et s3 ( int state ) {
fn_et next_state = FN_FINISH;
printf( "s3(%d)\n", state );
return next_state;
}
// table of functions, matching the enum
fn funcs[] = {
s1,
s2,
s3,
};
int main ( ) {
fn_et state = FN_S1;
while ( state != FN_FINISH ) {
state = funcs[state](123);
}
return 0;
}