mercredi 30 décembre 2015

Conventions for functions that operate on structs

Let's say I have the following in foo.h:

typedef struct {
    char* my_buf;
    int my_int;
} MyFoo;

/* Creates a foo, allocating memory for my_buf and initializing my_int */
void init_foo(MyFoo *foo);
/* Destroys a foo, freeing the memory for my_buf */
void free_foo(MyFoo *foo);

Now in another module, bar.h let's say I have the following:

#include "foo.h"

/* Do something with a foo */
void do_something(MyFoo *foo, SomeType_t otherType, ...);

As written, it's unclear whether or not the MyFoo provided to do_something should have been initialized with create_foo. Since it's not const, I think it's reasonably clear that a foo (i.e. space allocated for a foo) should be passed in, it will be modified in some way, and then the user can use the modified foo. But how do I most effectively indicate whether or not that foo should have been 'created'? A common pattern is to do something like

MyFoo stackFoo;
do_something(&stackFoo, ...);

But then, if do_something creates the foo, the user has to know that they're responsible for freeing the foo. On the other hand, there's no way to enforce that the foo should have been created; I'm just asking for a pointer (I admit this is a weak counter argument since it applies to a lot of things in C).

Another option would be to have MyFoo include a "created" flag so that it the function can reject any foos that haven't been created, but this seems like I'm over-engineering things.

I just want to be sure I'm not missing a common convention or standard way of handling this. Maybe I'm forcing OOP too much. Thoughts and comments appreciated!

Aucun commentaire:

Enregistrer un commentaire