Search code examples
cpointersstructhashtablevoid-pointers

Conversion to (void *) from different types in structure


I am trying to implement my own hash table as practice and I have structure defined as:

struct htab_item_t {
    char *key;
    int *value;
    struct htab_item_t *next;

But now I am considering switching to structure defined below and retype each input value to (void *), because then the table could be initialized for different types and it would be left for user to decide which one he wants. It should be possible as pointers are of the same byte lenght for each type.

struct htab_item_t {
    char *key;
    void *value;
    struct htab_item_t *next;

But my questin is, if it considered bad practice and if it could be harmful.


Solution

  • It is a good practice and a bad practice and could be harmful.

    C is an old language and has little support for polymorphism. To manage objects of multiple types, it is necessary to use void *. So it is good practice, because that is what you have to do in C.

    Nonetheless, programs using this are at some increased risks of bugs, which is in part why other languages were developed with better support for polymorphism. It could be bad practice to use C for something like this if you have the option of using another language.

    Primarily, you should take care that, when using the value retrieved from a struct htab_item_t, the actual object type is known, and the pointer is properly converted to that type before accessing the object.

    It should be possible as pointers are of the same byte lenght for each type.

    This is not guaranteed by the C standard. Aside from some specific constraints, pointers to different types may be different sizes.

    However, that is not a problem here because you will not be storing pointers to different types. When a pointer is stored in the value field, it will be converted to void *. When a pointer is read from the value field, it will be converted to its appropriate type. So what is stored in value will always be a void * and will have the appropriate size.

    The C rules for pointer conversions guarantee that this will always work for pointers to objects, as long as the correct type is used to access each object.