Coming from OO (C#, Java, Scala) I value very highly the principles of both code reuse and type-safety. Type arguments in the above languages do the job and enable generic data structures which are both type-safe and don't 'waste' code.
As I get stuck into C, I'm aware that I have to make a compromise and I'd like it to be the right one. Either my data structures have a void *
in each node / element and I lose type safety or I have to re-write my structures and code for each type I want to use them with.
The complexity of the code is an obvious factor: iterating through an array or a linked-list is trivial and adding a *next
to a struct is no extra effort; in these cases it makes sense not to try and re-use structures and code. But for more complicated structures the answer isn't so obvious.
There's also modularity and testability: separating out the type and its operations from the code that uses the structure makes testing it easier. The inverse is also true: testing the iteration of some code over a structure whilst it's trying to do other things gets messy.
So what's your advice? void *
and reuse or type-safety and duplicated code? Are there any general principles? Am I trying to force OO onto procedural when it won't fit?
Edit: Please don't recommend C++, my question is about C!
I would say use void *
so you can re-use the code. It's more work to re-implement e.g. a linked list, than to make sure you get/set the data in the list properly.
Take as many hints from glib as possible, I find their data structures very nice and easy to use, and have had little trouble because of the loss of type safety.
I think you'll have to strike a balance between the two, just as you suggest. If the code is only a few lines and trivial I would duplicate it but if it's more complex, I would consider working with void*
to avoid having to do any potential bug fixing and maintenance in several places and also to reduce the code size.
If you look at the C runtime library, there's several "generic" functions that work with void*
, one common example is sorting with qsort
. It would be madness to duplicate this code for every type you'd like to sort.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With