Casting between void pointers and function pointers is, strictly speaking, undefined behavior. Though it does tend to work, it's not something to rely on.
(And you don't need casts when converting between void pointers and data pointers)
Remember that this is for c, not c++. Void pointers are entirely unnecessary in c++ unless you’re interoperating with existing libraries and can’t change the interface. You’ll get faster and safer code with templates and function overloading
From my experience, learning a language like C goes beyond what you cover in University. Either that or the one I went to was **.
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.
This is a bit of a pet peeve with anonymous Internet writing, but: are we supposed to know when you were at university? Do you know when I was? Why not state something like the number of decades or whatever?
And yeah, a void * is how you express pointer to data of unknown type in C.
> This is a bit of a pet peeve with anonymous Internet writing, but: are we supposed to know when you were at university? Do you know when I was? Why not state something like the number of decades or whatever?
Does it matter? I tend to read it as "haven't touched it/had any use for it since university".
"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.