typedef void* var;
struct Header {
var type;
};
// ...
#define alloc_stack(T) header_init( \
(char[sizeof(struct Header) + sizeof(struct T)]){0}, T)
var header_init(var head, var type) {
struct Header* self = head;
self->type = type;
return ((char*)self) + sizeof(struct Header);
}
The section "struct Header* self = head" is UB.
The alignement requirement of the local char array is 1 but the alignment
requirement of struct Header is that of void* which is probably 8.
Even if the map is crucial for some reason, why not have the map take a simple value (like a unint64) and require the caller to convert their string into a slot before looking up the function pointer. That way the cost to exchange the string becomes obvious to the reader of the code.
I struggle to find a use case where this would optimize good code. I can think of plenty of bad code usecases, but are we really optimizing for bad code?
Your proposed solution is to have the user manually implement a hash table, but if you have a good optimizer, users can focus on writing clear code without bugs or logic errors and let the machine turn that into efficient code.