Search code examples
cfunction-pointers

How to define a function pointers and and structure?


How to define a function pointers with a structure as parameter... and that structure contains the function pointer ?

This code doesn't compile :

typedef struct _INFOS_STRUCT {
    int val1;

    PTR_NEXT_ACTION nextAction;
    //void* (*nextAction)(struct _INFOS_STRUCT  * infos); // how to replace void* by PTR_ACTION* ?
} INFOS_STRUCT;
typedef void (*PTR_ACTION)(INFOS_STRUCT * infos);
typedef PTR_ACTION (*PTR_NEXT_ACTION)(INFOS_STRUCT * infos);

INFOS_STRUCT infos_list[10];
void run(int index){
    INFOS_STRUCT * infos = &infos_list[index];
        
    PTR_ACTION action = infos->nextAction(infos);
    while(action){
        action(infos);
        action = infos->nextAction(infos);
    }
}

Solution

  • One possible way:

    //do the typedef first, on a forward declaration
    typedef struct INFOS_STRUCT INFOS_STRUCT
    typedef void (*PTR_ACTION)(INFOS_STRUCT * infos);
    typedef PTR_ACTION (*PTR_NEXT_ACTION)(INFOS_STRUCT * infos);
    struct INFOS_STRUCT {
        int val1;
        PTR_NEXT_ACTION nextAction;
    };
    

    Note: Changed the tag from _INFO_STRUCT to INFO_STRUCT. _INFO_STRUCT is a reserved name. You could use INFO_STRUCT_ (not reserved) if you need the tag to differ from the typedef name.


    Explanation:

    The idea is simple. Once you forward declare a struct or union like with:

    struct foo; 
    union bar;
    

    You can declare/define pointers to it such as

    struct foo *ptr0;
    union bar ***ptr1;
    

    If the pointer definitions are in another struct/union definition that's at the same scope or at just plain in the same scope scope, you don't even need the forward declaration (note that function parameters, even in a declaration, are in a nested scope, so you do need the forward declaration in struct foo; void takefooptr(struct foo*);).

    When you then follow a forward declare struct foo with struct foo { /*...*/ }; the type gets completed and you can start declaring actual struct foo variables rather than just pointers.

    If want to skip the struct/union keyword in later uses, you can typedef the forward declaration:

    struct foo;
    typedef foo foo; //or typedef foo SOMENEWNAME;
    

    or do it in one step

    typedef struct foo foo;
    

    As a quirk of the C standards, this forward-declaration thing is not allowed for enums. Structs and enums only.