6

I would like to define a hash table with a swappable hash function. The hash function would take a pointer to the hash table and the key to be hashed, returning an int like so:

typedef int (hash_function_t) (hashtable *, int);

where the hashtable stores a pointer to the function that will be used to hash keys:

typedef struct ht {
  size_t size;
  ...
  hash_function_t *hash_function;
} hashtable;

Unfortunately this creates a circular reference.

I need the pointer to the hashtable in the hash function definition, so I can do a modulus against the hashtable size, so it doesn't go past the max number of buckets. I need the hash function in the hashtable so that I don't have to pass the hash function pointer all over the place.

I realise this will lead to code like:

*ht->hash_function (ht, key)

which is a little weird, but I'm fine with that.

Putting the typedefs in either order doesn't work. Do I have to use the long definition in the hashtable and then do a typedef afterwards, or is there a better way?

This is all intended in straight C, no C++. ANSI C solutions preferred!

majelbstoat
  • 12,889
  • 4
  • 28
  • 26

1 Answers1

12

You can declare the structure before you use it in a definition. That tells the compiler that the structure exists, but it will be fully defined later. Something like this:

/* declare it first */
struct ht;

typedef int (hash_function_t) (struct ht *, int);

typedef struct ht {
  size_t size;
  ...
  hash_function_t *hash_function;
} hashtable;
Martin Kosek
  • 398
  • 3
  • 8