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.
You could do this:
size_t (*hashFunc)(void* key, size_t size) = (sizeof(size_t) == 8) ? hash8 : hash4;
There's also nothing wrong with eznme's approach -- write a single function that behaves differently according to the size of size_t
. Provided that you don't need the hash4
function for other purposes on 64bit implementations, of course.
Regarding the title of the question -- if you absolutely need to know about size_t
at preprocessor time, then use the SIZE_MAX
macro from stdint.h
.