Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - function inside struct

Tags:

c

function

struct

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 ?

like image 699
xRed Avatar asked Jun 11 '13 19:06

xRed


People also ask

Can you put a function inside a struct in C?

You cannot have functions in structs in C; you can try to roughly simulate that by function pointers though.

Can you define a function inside a struct?

No, you can't. Structs can only contain variables inside, storing function pointers inside the struct can give you the desired result.

Can you store a function in a struct?

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.


2 Answers

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.

like image 110
FatalError Avatar answered Oct 11 '22 21:10

FatalError


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.

like image 42
jxh Avatar answered Oct 11 '22 21:10

jxh