I have the following hashmap:
typedef uint32_t (*HashFuncPointer)(uint32_t key);
typedef bool (*KeyComparisonFunc)(uint32_t key1, uint32_t key2);
typedef struct Hashmap {
void* items;
uint64_t max_size;
uint64_t count;
uint64_t value_size;
HashFuncPointer hash_func;
KeyComparisonFunc key_comparison_func;
} Hashmap;
This hashmap has it’s hash_func set during initialisation and is never changed afterwards. However, calling these function pointers within my hashmap functions compiles to indirect calls:
uint32_t example_func(Hashmap* map) {
uint32_t value = map->hash_func(123);
return value;
}
Using GCC 14.2 for x86_64, compiles into:
example_func:
mov rax, QWORD PTR [rdi+40] // <--- Want to avoid this
mov edi, 123
jmp rax
Obviously, my example_func doesn’t know what the map being passed uses as it’s hash_func, so it indirectly calls it, but this is preventing optimization/inlining. This kind of sucks since the function a hashmap is using should always be known at compile time. C++ has constexpr for this, and similarly in C++ I can set the function pointer to be a constant. But in C, if you try to assign the value of a const member variable of a struct allocated on the heap, it is an error at worst, and, from my understanding, undefined behaviour at best. Is there a way to solve this without having to create a seperate struct each time I want my hashmap to have a different hash function?
7