TechZilla TechZilla - 2 months ago 6
C Question

Attempting more generic c code, custom data structure, in double linked list, this possible?

I'm attempting to refactor some code, to reduce duplication.

This is a curated example, currently defined in each .c file.

struct hrentry_t
{
int custom1;
int custom2;
int custom3;

struct hrentry_t *prev, *next;
};

struct hrentry_t*
attachentry(struct hrentry_t* hentry)
{
struct hrentry_t* hnew = calloc(sizeof(struct hrentry_t), 1);
if (hnew == NULL)
return NULL;

if (hentry != NULL) {
while (hentry->next != NULL) {
hentry = hentry->next;
};
hentry->next = hnew;
hnew->prev = hentry;
}
return hnew;
}


https://github.com/techzilla/check_snmp_extras, is the entire codebase.

I'm declaring and initializing a custom double linked list, and corresponding allocate function. If I moved the linked list functions and code to the common lib .c and .h, how can I get the file specific data inside of each list entry? Each file requires different types and number of variables.

Maybe I make a the double linked list contain only prev next and data? Then somehow make data a handle to an incomplete struct? How would then that need to be allocated though? I'm open to fully reconsidering my approach, so solid advice from experienced coders is always appreciated.

Answer Source

One approach is to make your specialized list data types castable to a generic double-linked list structure. This can be accomplished by putting the non-specialized data members at the beginning of the structure:

struct node_t {
    struct node_t * prev, * next;
};

struct hrentry_t
{
    struct node_t node;

    int custom1;
    int custom2;
    int custom3;
};

It then makes sense to cast an hentry_t* to a node_t*. The signature of your attachment function becomes:

struct node_t* attachentry(struct node_t* node);

And to use it, you cast instances of your specialized type to the generic type:

struct hentry_t * my_hentry_ptr;  /* initialized somehow... */
my_list = attachentry((struct node_t*)my_hentry_ptr);