Suppose I have a generic container, say, a list, that holds objects of unknown type. I want to copy everything into the container behind the scenes. I’ve come quite far with copy and destruction callbacks and internal storage declared as char*
, so I can have memory blocks of arbitrary size. Roughly like this:
typedef void (*copy_f)(void *dest, const void *src);
typedef void (*destroy_f)(void *element);
typedef struct ListNode {
struct ListNode *next,
char *data,
} ListNode;
typedef struct List {
ListNode *head,
copy_f copy_element, // these two can be NULL
destroy_f destroy_element,
size_t element_size,
} List;
// ...
ListNode *ListNode_new(const List *L, const void *element) {
ListNode *n = malloc(sizeof(*n));
n->data = malloc(L->element_size);
L->copy_element(n->data, element);
// or use memcpy if L->copy is NULL
// ...
}
// ...
It works. I can use this with arbitrarily nested types and according destructors and copy constructors, but it feels like a hack. It also results in a lot of ugly compiler warnings about incompatible pointer types. (The function typedefs have void*
, but I don’t want to cast from void*
to the actual type in a string destructor or every simple int comparison callback.)
The more I dig, the more I appreciate C++ and the STL. C is probably just not meant to be used like this, but is there a better way?