C - function inside the structure

I am trying to create a function inside a structure, 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 to' {token.

What is the right way to do this?

+45
c function struct
Jun 11 '13 at 19:46
source share
5 answers

This cannot be done directly, but you can emulate the same thing using function pointers and explicitly pass 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, is actually not very expensive for you. This way, you will not see many C APIs implemented in this style, as you can just call your external function and pass the instance.

+69
Jun 11 '13 at 19:53
source share
— -

As others have pointed out, built-in function pointers directly inside your structure are usually reserved for special purposes, such as a callback function.

What you probably want is 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 flexibility is only useful if you need to define many types of clients or want users of your client_t interface to client_t able to increase the behavior of operations.

Such a structure is displayed in real code. The OpenSSL BIO layer is similar to this, and UNIX device driver interfaces also have this layer.

+17
Jun 11 '13 at 21:01
source share

This will only work in C ++. Functions in structures are not a feature of C.

The same goes for your client .AddClient (); call ... this is a call to a member function, which is object-oriented programming, i.e. C ++.

Convert the source code to a .cpp file and make sure that you compile it appropriately.

If you need to stick with C, the code below is (sort of) equivalent:

 typedef struct client_t client_t, *pno; struct client_t { pid_t pid; char password[TAM_MAX]; // -> 50 chars pno next; }; pno AddClient(pno *pclient) { /* code */ } int main() { client_t client; //code .. AddClient(client); } 
+10
Jun 11 '13 at 19:47
source share

How about this?

 #include <stdio.h> typedef struct hello { int (*someFunction)(); } hello; int foo() { return 0; } hello Hello() { struct hello aHello; aHello.someFunction = &foo; return aHello; } int main() { struct hello aHello = Hello(); printf("Print hello: %d\n", aHello.someFunction()); return 0; } 
+4
Oct 6 '15 at 7:55
source share

You are trying to group the code according to structure. Group by file. You put all functions and internal variables in the header or header and the ".o" file of the object compiled from the source file c.

There is no need to reinvent object orientation from scratch for a C program that is not an object oriented language.

I have seen this before. This is strange. Some coders have an aversion to passing the object they want to change into a function to change it, although this is the standard way to do this.

I blame C ++ because it hid the fact that the class object is always the first parameter in a member function, but it is hidden. So it looks like it is not passing an object to a function, even if it is.

 Client.addClient(Client& c); // addClient first parameter is actually // "this", a pointer to the Client object. 

C is flexible and can accept transfer things by reference.

The C function often returns only a status byte or int, and this is often ignored. In your case, the correct form may be

  err = addClient( container_t cnt, client_t c); if ( err != 0 ) { fprintf(stderr, "could not add client (%d) \n", err ); 

addClient will be in Client.h or Client.c

0
Jun 14 '17 at 7:41
source share



All Articles