Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly define a function pointer in struct, which takes struct as a pointer?

I have a struct with a callback function, the callback function needs a pointer to the structure in order to do its operation. How do I properly define these elements such that is will compile without warnings?

typedef struct {

    // some fields required for processing...

    int (*doAction)(struct pr_PendingResponseItem *pr);
} pr_PendingResponseItem;

If I remove the "struct" attribute on the pr parameter, I get an error. If I leave it in, I get a warning: "its scope is only this definition or declaration, which is probably not what you want"

It all works, but I would like to know the proper way to define such a structure.

Also related, is defining a self referential structure:

typedef struct LinkedItem_ {
    LinkedItem_ * prev;
    LinkedItem_ * next;
    void * data;
} LinkedItem;

(I think this is correct, but additional thoughts are welcome if it is related to the question.)

like image 209
JeffV Avatar asked Oct 01 '10 12:10

JeffV


People also ask

Can a structure struct contain a pointer to itself?

A structure containing a pointer to itself is not a problem. A pointer has a fixed size, so it doesn't matter how big the size of the structure it points to is. On most systems you're likely to come across, a pointer will be either 4 bytes or 8 bytes in size.

Is it possible to declare function pointer in structure yes or no?

No, you cannot define a function within a struct in C. You can have a function pointer in a struct though but having a function pointer is very different from a member function in C++, namely there is no implicit this pointer to the containing struct instance.


2 Answers

Your function pointer references a struct pr_PendingResponseItem, but you haven't declared a struct pr_PendingResponseItem. You just have an unnamed structure typedef'ed to the name pr_PendingResponseItem (and that name isn't established yet).

Give the struct a name:

struct pr_PendingResponseItem {

    // some fields required for processing...

    int (*doAction)(struct pr_PendingResponseItem *pr);
} ;
typedef struct pr_PendingResponseItem pr_PendingResponseItem;
like image 53
nos Avatar answered Oct 18 '22 23:10

nos


There are two ways to do it — for both your example structures. They are essentially isomorphic.

  1. Use a structure tag, as already shown in various other answers.

    typedef struct pr_PendingResponseItem
    {
        // some fields required for processing...
        int (*doAction)(struct pr_PendingResponseItem *pr);
    } pr_PendingResponseItem;
    
    typedef struct LinkedItem
    {
        struct LinkedItem *prev;
        struct LinkedItem *next;
        void * data;
    } LinkedItem;
    
  2. Use typedef to give a name to an incomplete structure type and use the typedef in the structure definition.

    typedef struct pr_PendingResponseItem pr_PendingResponseItem;
    struct pr_PendingResponseItem
    {
        // some fields required for processing...
        int (*doAction)(pr_PendingResponseItem *pr);
    };
    
    typedef struct LinkedItem LinkedItem;
    struct LinkedItem
    {
        LinkedItem *prev;
        LinkedItem *next;
        void * data;
    };
    

Note that the structure tags are in a different namespace from the typedef names, so there is no need to use different names for the typedef and structure tag. Also note that in C++ the typedef would be unnecessary.

like image 32
Jonathan Leffler Avatar answered Oct 18 '22 22:10

Jonathan Leffler