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

前端 未结 3 1118
误落风尘
误落风尘 2021-02-14 13:14

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 recurs

相关标签:
3条回答
  • 2021-02-14 13:36

    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.

    0 讨论(0)
  • 2021-02-14 13:39

    I suspect what you are trying to do is a more complex version of something like this:

    typedef MainLoop *MainLoop(); // not legal
    
    extern MainLoop* main_loop_1();
    extern MainLoop* main_loop_2();
    
    MainLoop* main_loop_1()
    {
        // do some work here
        return main_loop_2;
    }
    
    MainLoop* main_loop_2()
    {
        // do some work here
        return main_loop_1;
    }
    
    int main()
    {
        MainLoop f = main_loop_1;
    
        for (;;) {
          f = f();
        }
    }
    

    A workaround is to wrap the function pointer in a struct:

    struct MainLoop {
        MainLoop (*function_ptr)(); // legal
    };
    
    extern MainLoop main_loop_1();
    extern MainLoop main_loop_2();
    
    MainLoop main_loop_1()
    {
        // do some work here
        return {main_loop_2};
    }
    
    MainLoop main_loop_2()
    {
        // do some work here
        return {main_loop_1};
    }  
    
    int main()
    {
        MainLoop f{main_loop_1};
    
        for (;;) {
           f = f.function_ptr();
        }
    }
    
    0 讨论(0)
  • 2021-02-14 13:54

    The trick in C is to take advantage of the fact that any kind of function pointer can be cast to any other kind of function pointer:

    #include <stdlib.h>
    #include <stdio.h>
    
    typedef void(*emptyfunc)(void);
    typedef emptyfunc (*funcptr2)(int);
    
    funcptr2 strategy(int m)
    {
      printf("Strategy %d.\n", m);
      return (funcptr2)&strategy;
    }
    
    int main (void)
    {
      const funcptr2 strategy2 = (funcptr2)strategy(1);
      const funcptr2 strategy3 = (funcptr2)strategy2(2);
      strategy3(3);
    
      return EXIT_SUCCESS;
    }
    

    Each pointer to a strategy is always in a type that can be called once, and the return value is put back into a form that can be called once again.

    In C++, you would declare a function object:

    class strategy {
      public:
      virtual const strategy& operator()(int) const = 0;
    }
    

    An instance of this class can be called like a function.

    0 讨论(0)
提交回复
热议问题