Im trying to assign a function inside a struct
, so far I have this code:
typedef struct client_t client_t, *pno; struct client_t { pid_t pid; char password[TAM_MAX]; // -> 50 chars pno next; pno AddClient() { /* code */ } }; int main() { client_t client; // code .. client.AddClient(); }
**Error**: *client.h:24:2: error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘{’ token.*
Which is the correct way to do it ?
You cannot have functions in structs in C; you can try to roughly simulate that by function pointers though.
No, you can't. Structs can only contain variables inside, storing function pointers inside the struct can give you the desired result.
Function pointers can be stored in variables, structs, unions, and arrays and passed to and from functions just like any other pointer type. They can also be called: a variable of type function pointer can be used in place of a function name.
It can't be done directly, but you can emulate the same thing using function pointers and explicitly passing the "this" parameter:
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); }
It turns out that doing this, however, doesn't really buy you an awful lot. As such, you won't see many C APIs implemented in this style, since you may as well just call your external function and pass the instance.
As others have noted, embedding function pointers directly inside your structure is usually reserved for special purposes, like a callback function.
What you probably want is something more like a virtual method table.
typedef struct client_ops_t client_ops_t; typedef struct client_t client_t, *pno; struct client_t { /* ... */ client_ops_t *ops; }; struct client_ops_t { pno (*AddClient)(client_t *); pno (*RemoveClient)(client_t *); }; pno AddClient (client_t *client) { return client->ops->AddClient(client); } pno RemoveClient (client_t *client) { return client->ops->RemoveClient(client); }
Now, adding more operations does not change the size of the client_t
structure. Now, this kind of flexibility is only useful if you need to define many kinds of clients, or want to allow users of your client_t
interface to be able to augment how the operations behave.
This kind of structure does appear in real code. The OpenSSL BIO layer looks similar to this, and also UNIX device driver interfaces have a layer like this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With