Неразрешимая собственная ссылка
Это невозможно напрямую.Если вы попытаетесь определить тип указателя на функцию, где тип возвращаемого значения функции является ее собственным типом, вы столкнетесь с неразрешенной собственной ссылкой, для решения которой потребуется бесконечная рекурсия.
typedef funcType (*funcType)(void);
Возврат struct
Вместо этого можно объявить, что функция возвращает структуру, и структура может содержать указатель на такую функцию.
struct func {
struct func (*func) (void);
};
struct func foo (void);
struct func bar (void);
struct func foo (void) { return (struct func){ bar }; }
struct func bar (void) { return (struct func){ foo }; }
...
struct func funcPtr = { foo };
funcPtr = funcPtr.func();
Возвращать другой тип указателя на функцию
Если вы предпочитаете строго придерживаться указателей, вам придется прибегнуть к определению функций, которые возвращают другой тип указателя на функцию.Таким образом, результат вызова должен быть приведен обратно к правильному типу указателя перед вызовом.
typedef void (*funcPtrType)(void);
typedef funcPtrType funcType(void);
funcType foo;
funcType bar;
funcPtrType foo (void) { return (funcPtrType)bar; }
funcPtrType bar (void) { return (funcPtrType)foo; }
...
funcType *p = foo;
p = (funcType *)p();
Вернуть индекс †
Вы могли бы вместо этогоопределите свои функции, чтобы возвращать индекс к таблице, которая представляет функцию, которая должна быть вызвана.
enum funcEnum { fooEnum, barEnum };
typedef enum funcEnum (*funcType)(void);
enum funcEnum foo (void) { return barEnum; }
enum funcEnum bar (void) { return fooEnum; }
funcType funcTable[] = { [fooEnum] = foo, [barEnum] = bar };
...
funcType p = funcTable[fooEnum];
p = funcTable[p()];
† Это было поднято в комментариях и в ответ Павла , но представленздесь для полноты.