"void* ht_get(...)"
Wait. What? A void pointer? Interesting... I have no clue.
I like articles like these. For someone not familiar with C it's a perfect level. In terms of explanation and the code itself.
"void* ht_get(...)"
Wait. What? A void pointer? Interesting... I have no clue.
I like articles like these. For someone not familiar with C it's a perfect level. In terms of explanation and the code itself.
The main use case is generic functions. And in data structures like this.
(And you don't need casts when converting between void pointers and data pointers)
It might be undefined in the sense that a language lawyer might care, but for any sane implementation it’s completely valid.
In practice though, it works pretty much everywhere in my experience.
I remember back in the late 90s to early 00s, I had fun countering OOP guys claiming C "cannot do XYZ" - but it obviously can.. the C way.
For method override, my mind was blown when I discovered function pointers!
It was my "Wait. What?" moment.. along with various other things!
Below is sample code (not tested)
// generic monster "class"
struct monster_t {
int health;
struct weapon_t *weapon;
// etc..
void (*attack)(struct monster_t *self); // our function pointer
// more function pointers for update, die, hit, etc...
};
// impl
void monster_notassigned_attach(struct monster_t *monster) { // safety net (todo)
printf("Attack not assigned to monster...\n");
}
void monster_dragon_attack(struct monster_t *monster) {
// attack for dragon
printf("Dragon is attacking you...\n");
}
void monster_wizard_attack(struct monster_t *monster) {
// attack for wizard
printf("Wizard is attacking you...\n");
}
// creation
void monster_dragon_create(struct monster_t *monster) {
// allocate, then assign.. and do...
monster->attack = monster_dragon_attack;
}
void monster_wizard_create(struct monster_t *monster) {
// allocate, then assign.. and do...
monster->attack = monster_wizard_attack;
}
void main() {
// testing...
struct monster_t monsters[10]; // can store various monsters!
monster_dragon_create(&monsters[0]);
monster_wizard_create(&monsters[1]);
for(int i = 0; i < 2; ++i) {
monsters[i].attack(&monsters[i]); // yeah you have to pass it in...
}
}
Not suggesting I support or follow the above especially for games. It is just a proof of concept!
I always tell people that coding in C (or any non-OOP language) should not be done the way you would in Java, C#, etc. As mentioned, the above is a demonstration.And yeah, a void * is how you express pointer to data of unknown type in C.
Does it matter? I tend to read it as "haven't touched it/had any use for it since university".