Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a function pointer to a function returning a function pointer to a function?

I want to assign a function's address to a function pointer, but the function to be addressed returns a function pointer with the same signature as itself, causing it to recurse in a way that I can't write the return type at all, for the function pointer or even the function declaration itself...

I guess a way of simplifying the problem so it's not confusing:

How could I write a function declaration such, that it can return a pointer to itself (or any other function with the same signature)?

????? function(int a){
    // could be this function, or another with the same signature, 
    return arbitraryFunction;  
}

?????(*func)(int) = function;  // same problem as above

edit:

For now I have a solution, though I won't post it as an answer because it's aggressively ugly. It gets rid of the recursion by simply returning a raw void* pointer as the return type, and ends up taking the following form:

void* function(int parameter){
    return arbitraryFunction; // of the same signature
}

void*(*func)(int) = function; 
func = reinterpret_cast<void*(*)(int)>(func(42));  // sin

edit2:

It seems casting between function pointers and regular pointers is UB, so I can't use void* in this case...

To answer one of the comments, this is for passing control between multiple "main" loops in my program, with each loop getting it's own function. There's a lot of ways to do this, but returning function pointers (or NULL to terminate the program) mid-loop seemed like the simplest method, but I didn't anticipate that pointers to data and pointers to function addresses would be incompatable with each other. I think returning polymorphic function objects will end up being the more sane option in this case.

like image 516
Anne Quinn Avatar asked Sep 27 '15 15:09

Anne Quinn


People also ask

How can a function return a pointer to a function?

Return Function Pointer From Function: To return a function pointer from a function, the return type of function should be a pointer to another function. But the compiler doesn't accept such a return type for a function, so we need to define a type that represents that particular function pointer.

How do you write a pointer to a function?

Function Pointer Syntaxvoid (*foo)( int ); In this example, foo is a pointer to a function taking one argument, an integer, and that returns void. It's as if you're declaring a function called "*foo", which takes an int and returns void; now, if *foo is a function, then foo must be a pointer to a function.

Is it possible to return of pointer from a function?

We can pass pointers to the function as well as return pointer from a function. But it is not recommended to return the address of a local variable outside the function as it goes out of scope after function returns.


1 Answers

Don't use void*, because no guarantee that a void * can hold a function pointer. You can use void(*)() as a workaround:

typedef void(*void_func)();
typedef void_func (*func_type) (int);
void_func arbitraryFunction(int a) {
    // could be this function, or another with the same signature, 
    cout << "arbitraryFunction\n";
    return nullptr;  
}
void_func function(int a) {
    // could be this function, or another with the same signature, 
    return (void_func) arbitraryFunction;  
}
int main() {
    // your code goes here
    func_type f = (func_type) function(0);
    f(0);
    return 0;
}

LIVE

C99 [6.2.5/27]:

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

C99 [6.3.2.3/8]:

A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer.

like image 143
songyuanyao Avatar answered Oct 06 '22 04:10

songyuanyao