Function Returning Itself

2019-01-07 11:15发布

问题:

Is it possible to declare some function type func_t which returns that type, func_t?

In other words, is it possible for a function to return itself?

// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
  return &foo;
}

Or would I have to use void * and typecasting?

回答1:

No, you cannot declare recursive function types in C. Except inside a structure (or an union), it's not possible to declare a recursive type in C.

Now for the void * solution, void * is only guaranteed to hold pointers to objects and not pointers to functions. Being able to convert function pointers and void * is available only as an extension.



回答2:

A possible solution with structs:

struct func_wrap
{
    struct func_wrap (*func)(void);
};

struct func_wrap func_test(void)
{
    struct func_wrap self;

    self.func = func_test;
    return self;
}

Compiling with gcc -Wall gave no warnings, but I'm not sure if this is 100% portable.



回答3:

You can't cast function pointers to void* (they can be different sizes), but that's not a problem since we can cast to another function pointer type and cast it back to get the original value.

typedef void (*fun2)();
typedef fun2 (*fun1)();

fun2 rec_fun()
{
    puts("Called a function");
    return (fun2)rec_fun;
}

// later in code...
fun1 fp = (fun1)((fun1)rec_fun())();
fp();

Output:

Called a function
Called a function
Called a function


回答4:

In other words, is it possible for a function to return itself?

It depends on what you mean by "itself"; if you mean a pointer to itself then the answer is yes! While it is not possible for a function to return its type a function can return a pointer to itself and this pointer can then be converted to the appropriate type before calling.

The details are explained in the question comp.lang.c faq: Function that can return a pointer to a function of the same type.

Check my answer for details.



回答5:

what about something like this:

typedef void* (*takesDoubleReturnsVoidPtr)(double);

void* functionB(double d)
{
    printf("here is a function %f",d);
    return NULL;
}

takesDoubleReturnsVoidPtr functionA()
{
    return functionB;
}

int main(int argc, const char * argv[])
{
    takesDoubleReturnsVoidPtr func = functionA();
    func(56.7);
    return 0;
}


回答6:

Assume the function definition

T f(void)
{
  return &f;
}

f() returns a value of type T, but the type of the expression &f is "pointer to function returning T". It doesn't matter what T is, the expression &f will always be of a different, incompatible type T (*)(void). Even if T is a pointer-to-function type such as Q (*)(void), the expression &f will wind up being "pointer-to-function-returning-pointer-to-function", or Q (*(*)(void))(void).

If T is an integral type that's large enough to hold a function pointer value and conversion from T (*)(void) to T and back to T (*)(void) is meaningful on your platform, you might be able to get away with something like

T f(void)
{ 
  return (T) &f;
}

but I can think of at least a couple of situations where that won't work at all. And honestly, its utility would be extremely limited compared to using something like a lookup table.

C just wasn't designed to treat functions like any other data item, and pointers to functions aren't interchangeable with pointers to object types.



回答7:

There's a way, you just try this:

typedef void *(*FuncPtr)();

void *f() { return f; }

int main() {
    FuncPtr f1 = f();
    FuncPtr f2 = f1();
    FuncPtr f3 = f2();
    return 0;
}


回答8:

If you were using C++, you could create a State object type (presuming the state machine example usage) wherein you declare an operator() that returns a State object type by reference or pointer. You can then define each state as a derived class of State that returns each appropriate other derived types from its implementation of operator().



标签: c function