I am creating an implementation of a hash table in C for educational purposes.
The hash function should return a size_t hash. Since the size of size_t is different in different platforms (and I want to use a hash function that hashes all the bits in a size_t), I thought of creating different hash functions for different sizes. As the hash function will be used as a function pointer, I suspect the compiler can't inline code like this:
size_t hash4(void* key, size_t size);
size_t hash8(void* key, size_t size);
size_t hash(void* key, size_t size)
{
if (sizeof(size_t) == 4)
{
return hash4(key, size);
}
else if (sizeof(size_t) == 8)
{
return hash8(ket, size);
}
}
size_t (*hashFunc)(void* key, size_t size) = hash;
And two levels of indirection will be used each time the hash function will be called.
That's why I thought of doing something like this: size_t (*hashFunc)(void* key, size_t size) = hash##sizeof(size_t);
instead. Only one level of indirection will be used. The problem is that the sizeof operator isn't available during the prepossessing phase.
So what would be a good way to define a preprocessor value which will expand to the correct size of size_t in each platform? I guess I could check against predefined macros, but I wonder if there's a better way.
sizeof
is a C-operator. ##
is a preprocessor operator. The latter does not know anything about the former.
So you might be better of using a macro referring to the system's bit-width used for addressing, like for example testing like so:
#if UINTPTR_MAX == 0xffffffffffffffff
/* it's 64bits pointers */
#elif UINTPTR_MAX == 0xffffffff
/* it's 32bits pointers */
#endif
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