views:

387

answers:

1

In a project I'm writing code for, I have a void pointer, "implementation", which is a member of a "Hash_map" struct, and points to an "Array_hash_map" struct. The concepts behind this project are not very realistic, but bear with me. The specifications of the project ask that I cast the void pointer "implementation" to an "Array_hash_map" before I can use it in any functions.

My question, specifically is, what do I do in the functions to cast the void pointers to the desired struct? Is there one statement at the top of each function that casts them or do I make the cast every time I use "implementation"?

Here are the typedefs the structs of a Hash_map and Array_hash_map as well as a couple functions making use of them.

typedef struct {
  Key_compare_fn key_compare_fn;
  Key_delete_fn key_delete_fn;
  Data_compare_fn data_compare_fn;
  Data_delete_fn data_delete_fn;
  void *implementation;
} Hash_map;

typedef struct Array_hash_map{
  struct Unit *array;
  int size;
  int capacity;
} Array_hash_map;

typedef struct Unit{
  Key key;
  Data data;
} Unit;

functions:

/* Sets the value parameter to the value associated with the
   key parameter in the Hash_map. */
int get(Hash_map *map, Key key, Data *value){
  int i;
  if (map == NULL || value == NULL)
    return 0;
  for (i = 0; i < map->implementation->size; i++){
    if (map->key_compare_fn(map->implementation->array[i].key, key) == 0){
      *value = map->implementation->array[i].data;
      return 1;
    }
  }
  return 0;
}

/* Returns the number of values that can be stored in the Hash_map, since it is
   represented by an array. */
int current_capacity(Hash_map map){
  return map.implementation->capacity;
}
+3  A: 

You can cast it each time you use it, or you can cast it once and save the value to a temporary variable. The latter is usually the cleanest method.

For example, you could use something like:

void my_function (Hash_Map* hmap) {
    Array_hash_map* pMap;

    pMap = hmap->implementation;

    // Now, you are free to use the pointer like it was an Array_hash_map
    pMap->size = 3; // etc, etc
}
bta
I understand what you guys are saying, but one point of contention. The void pointer is actually a field of a Hash_map, and also points to an Array_hash_map. Can I still cast in the manner map->implementation = (Array_hash_map*) map->implementation;where map is a Hash_map passed into the function and implementation is the void pointer
Rowhawn
`map->implementation = (Array_hash_map *) map->implementation` would be a no-op. The type associated with a symbol in a given scope is fixed in C - if `map->implementation` is of type `void *`, it shall always be thus.
caf
I figured as much. I think I'll just make an Array_hash_map and set it to the void pointer, as was suggested. Thanks for the help!
Rowhawn