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 its 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?