0

I got the following code from here: C - function inside struct. I've been looking at it for an hour but I just don't understand it. Starting with the very first line: I know

typedef struct client_t client_t;

But how does the additional *pno work, what is it doing? Why is next never used? Where does *self come from?

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

        pno (*AddClient)(client_t *);    
};

pno client_t_AddClient(client_t *self) { /* code */ }

int main()
{

    client_t client;
    client.AddClient = client_t_AddClient; // probably really done in some init fn

    //code ..

    client.AddClient(&client);

}
  • As the comments and answer to the linked question say, you don't have a function in a struct (that's not legal in C). You have a function pointer in a struct. – Keith Thompson Feb 03 '20 at 23:17

1 Answers1

1

pno is a typedef to pointer to struct client_t.

typedef struct client_t client_t, *pno;

means the same as:

typedef struct client_t client_t;
typedef struct client_t *pno;

So client_t means the same as struct client_t and pno means the same as struct client_t *. Let's substitute them in your code.

struct client_t 
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        struct client_t *next;
        struct client_t *(*AddClient)(struct client_t *);    
};

struct client_t *client_t_AddClient(client_t *self) { /* code */ }

int main()
{

    struct client_t client;
    client.AddClient = client_t_AddClient; // probably really done in some init fn

    //code ..

    client.AddClient(&client);

}

So struct client_t has a member called next that is a pointer to struct client_t - classic linked list. The struct client_t *(*AddClient)(struct client_t *); is a function pointer declaration, that takes a pointer to struct client_t and returns a pointer to struct client_t - judging from the name, it adds next client to the current item, but I don't know what does it return because it hasn't been explained.

I discourage using typedefs to hide pointers - it makes your code less readable.

But how does the additional *pno work, what is it doing?

The additional *pno defines additional identifier pno to be a typedef to struct client_t * type.

Why is next never used?

Because you did not show where it's used. (?) It's impossible to answer that question without knowing the context.

Where does *self come from?

It's the identifier given the argument in the function client_t_AddClient definition. I believe it "comes" from writer of this code - he decided to name the argument to this function as "self". I guess it means it refers to the current object, as to mimic self keyword for example from python.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
KamilCuk
  • 120,984
  • 8
  • 59
  • 111