Thread: Function Pointer Typedef with Same Type Arguments

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    141

    Function Pointer Typedef with Same Type Arguments

    I need to create the following brain damaging abomination:
    I need a function pointer type to a function that has an argument of the same function pointer type and returns the same function pointer type.

    The purpose is to enable a type of subroutine threading scheme for a small application specific scripting language. The question could just as well have been posted to the C forum.

    This syntax works, but Payload is a generic type which I can coerce into the right pointer type via a cast. This is ugly IMHO. I could also hide it as a pointer in the FlipState class since I've forward declared this.

    But this is an extra indirection in a performance critical part of the code, and also ugly.

    Code:
    class FlipState ;
    typedef PayLoad (*FuncPtr) (FlipState *fs, PayLoad P) ;
    This syntax blows chunks using gcc on the other hand.
    Code:
    class FlipState ;
    typedef FuncPtr (*FuncPtr) (FlipState *fs, FuncPtr P) ;
    ^
    ./flip.h:172:17: error: typedef ‘FuncPtr’ is initialized (use decltype instead)
    ./flip.h:172:19: error: ‘FuncPtr’ was not declared in this scope
    typedef FuncPtr (*FuncPtr) (FlipState *fs, FuncPtr P) ;
    ^
    ./flip.h:177:5: error: ‘FuncPtr’ does not name a type
    FuncPtr func ;
    ^
    ./flip.h:190:5: error: ‘FuncPtr’ does not name a type
    FuncPtr func ; /* current executing function */
    ^
    This is hardly surprising. The compiler could not possibly understand what I was defining in the typedef. I think what I need is some kind of way to forward declare a function pointer type and then redefine it properly.

    Is such a think even possible or am I just SOL? This one is mind boggling. We know how to do this with classes or other complex data types, but the syntax eludes me for both C++ and C.

    Any suggestions?

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    In declaring a typedef for a function pointer, the format is as follows:

    Code:
    typedef ReturnType (*NewTypeName)(arguments...);
    In your declaration, you're using the same type name for the return type and the typedef name.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    141
    Yup I know this. My little problem is that the type of function pointer I'm trying to declare returns a pointer of the same type. Actually it also has an argument of the same type. The type is self referential. So far I"m going with the type casting solution, but I just had another interesting idea that goes something like this.

    Code:
    class FlipState ;
    class *FuncPtr ;
    
    typedef FuncPtr (*FuncPtr2) (FlipState *fs,FuncPtr P) ;
    typedef FuncPtr2 (*FuncPtr) (FlipState *fs,FuncPtr P) ;
    The intent is to pseudo forward declare a function pointer type that will resolve to the same type as FuncPtr in the hopes that the return types of FuncPtr will be identical.

    Unfortunately it doesn't compile for two reasons. One gcc doesn't seem to like the idea of forward declaring a class pointer. (Not sure why this would be true).

    The second is that even if you could via various machinations it won't accept the redefinition of FuncPtr as a function pointer instead of a class pointer.

    Next I don't think there is any mechanism for a forward declaration of a typedef outside of a class. So for now I'm punting and will have to use cast coercion to get what I want.

    If I wanted to use an extra level of indirection there are some cuter solutions such as replacing FuncPtr with a class and putting my recursive function type as a member function (method ) of that class.

    If any of you C++ geniuses have something more efficient I'd love to see it. Thanks for your help in advance.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    The intent is to pseudo forward declare a function pointer type that will resolve to the same type as FuncPtr in the hopes that the return types of FuncPtr will be identical.
    O_o

    You can't have a normal function in C/C++ which returns self or similar.

    The intermediate steps--two functions returning each other--you are using is just hiding the problem.

    Even if you could "pseudo-forward" the pointer, the type wouldn't be resolved until use leaving you trying to return an incompatible pointer.

    In other words, the type returned would conceptually change as the real definition is encountered by the compiler.

    I'd say that the simplicity of the `typedef' is also hiding the problem; the signature only looks so similar because the `typedef' looks so similar.

    Code:
    void DoSomething1(){}
    
    void (*DoSomething2())(){return(DoSomething1);}
    
    void (*(*DoSomething3())())(){return(DoSomething2);}
    
    void (*(*(*DoSomething4())())())(){return(DoSomething3);}
    If I wanted to use an extra level of indirection there are some cuter solutions such as replacing FuncPtr with a class and putting my recursive function type as a member function (method ) of that class.
    If you were going to use a class with specific member functions, why wouldn't you store the state for the next call?

    If any of you C++ geniuses have something more efficient I'd love to see it.
    You would need to use a class or similar, but you don't have to have a class with specific member functions as the type returned can be normalized despite the different signatures because the actual result can be temporarily erased. The idiomatic approach is your best bet given the current context, but I imagine that someone could offer a better solution if you told us what you were trying to do instead of just how you are trying to do it.

    I've included a variation on the theme, but you should strongly consider explaining what you are trying to accomplish.

    For the sake of information, you'll find the example easier to extend and make safe with C++11 features.

    Soma

    Code:
    struct SWrapper
    {
        typedef SWrapper (*RCallback)(int);
        SWrapper
        (
            RCallback fCallback
        ):
            mCallback(fCallback)
        {
        }
        operator RCallback()
        {
            return(mCallback);
        }
        RCallback mCallback;
    };
    
    #include <iostream>
    
    SWrapper DoSomethingA
    (
        int fWhatever
    );
    
    SWrapper DoSomethingB
    (
        int fWhatever
    );
    
    int main()
    {
        typedef SWrapper (*S)(int);
        S s(DoSomethingA(0));
        s = s(1);
        s = s(2);
        s = s(3);
        s = s(4);
    }
    
    SWrapper DoSomethingA
    (
        int fWhatever
    )
    {
        std::cout << "A: " << fWhatever << '\n';
        return(DoSomethingB);
    }
    
    SWrapper DoSomethingB
    (
        int fWhatever
    )
    {
        std::cout << "B: " << fWhatever << '\n';
        return(DoSomethingA);
    }
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    141
    OK that's interesting. So C++11 allows for arbitrary operator declarations? It's late so maybe I'm reading that wrong.

    What I'm trying to do is to facilitate the calling of a compiled array of function pointers that represents a "subroutine" in my toy application specific interpreter. The basic interpreter code would look something like this,

    Code:
    class FlipState ;
    typedef void * (*FuncPtr) (FlipState *fs, void * P) ;
    
    void * mycall(FlipState *fs, void *next) {
    FuncPtr fp = (FuncPtr) next ;
    while (fp) {
      fp =(FuncPtr) (fp)(fs, (void *) (fp+1)) ;
    }
    void *pnext = fs->pop() /* pops the return stack of the parent */
    return(pnext) ;
    }
    I haven't fully checked the syntax. But this represents an efficient way to call an array of functions of the same type under the condition that the calling ABI is some type of fastcall that uses registers for parameters, and that I have good locality of reference for the code and the function pointers that point to the code.

    If I start burying the function pointers through additional indirection I lose performance through unnecessary memory accesses. Yes performance is why I'm using C/C++ so it's important to me.

    Perhaps a good compiler would remap those indirections to registers, but this actually guarantees it for the fast call ABI interface. There is a hit in that I have to maintain my own return stack, but that's unavoidable and presumably much rarer than just executing the next sequential statement.

    Also notice all the unpleasant error prone typecasting, due to the function pointer type declaration limitation. Also note that I pass the proposed return value and allow it to be modified for simulating control instructions in my interpreter. Normally you leave it alone, but if you need to jump the return value gets modified.
    Last edited by SevenThunders; 04-01-2015 at 03:00 AM. Reason: code fix

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 10-07-2011, 01:54 PM
  2. typedef a function pointer question..
    By MegaManZZ in forum C++ Programming
    Replies: 2
    Last Post: 09-25-2008, 10:57 AM
  3. Replies: 9
    Last Post: 01-02-2007, 04:22 PM
  4. Typedef representing pointer to function
    By pdc in forum C Programming
    Replies: 3
    Last Post: 06-10-2005, 10:10 AM
  5. why typedef? and not a pointer to function?
    By terracota in forum Windows Programming
    Replies: 10
    Last Post: 12-19-2004, 06:22 PM

Tags for this Thread