An alternative could be to guarantee that the first two elements of the data structure are next and prev pointers. This way the implementation can just assume the first 8 or 16 bytes (depending on sizeof(void*)) are the next/prev addresses. Then the same set of functions can work with everything that looks like a linked list. Another option is to have a "struct list" that contains the information needed, and the API allows, when you initialize the list, to say how much space you want starting at "node->data". This way the node is always over-allocated by the library, and when you want to manipulate the list items you cast node->data to your privata data structure.