C/C++ casting issue?
Hi all,
My knowledge of 'C' is fine; but C++ under Xcode not so hot!
I simply cannot get this to compile; the error being:
error: cannot convert 'HIT_LIST*' to 'void (**)(OBJECT_DEF*, OBJECT_DEF*)' in initialization
Relevant code:
header files:
All I am trying to do is setup HIT_LIST as an array of pointers to functions expecting (OBJECT_DEF *,OBJECT_DEF *) as input.
But the initialization of it SPAWN_DEF fails with the error.
Anyone care to help?; I assume it's a feature of xcode implementation or C++ causing casting issues that I am struggling to overcome.
Cheers
My knowledge of 'C' is fine; but C++ under Xcode not so hot!
I simply cannot get this to compile; the error being:
error: cannot convert 'HIT_LIST*' to 'void (**)(OBJECT_DEF*, OBJECT_DEF*)' in initialization
Relevant code:
Code:
void no_hit(OBJECT_DEF *obj1,OBJECT_DEF *obj2)
{
}
HIT_LIST hit_BLAST=
{
&no_hit, // 0
};
SPAWN_DEF def_type_blast=
{
&hit_BLAST, <--------problem here
};Code:
typedef struct SPAWN_DEF
{
void (**hit_list_ptab)(OBJECT_DEF *,OBJECT_DEF *);
};
typedef struct HIT_LIST
{
void (*hit_func)(OBJECT_DEF *,OBJECT_DEF *);
};But the initialization of it SPAWN_DEF fails with the error.
Anyone care to help?; I assume it's a feature of xcode implementation or C++ causing casting issues that I am struggling to overcome.
Cheers
I think &(hit_BLAST.hit_func) will compile... that's nothing to do with Xcode, or even GCC/Clang, the code is just plain not valid as it stands.
The code is horrible, too. Double-pointer-to-function? WTH?
The code is horrible, too. Double-pointer-to-function? WTH?
:-)
Well it compiles!; not sure if it works correctly yet as other things to add.
Why does my method seem horrible?
Can you suggest a nicer way (in straight C) to have a pointer to a table of function pointers?
Cheers though!!
P.S It is strange though. As I wrote this code many years ago for ps1 and it obviously compiled then. Looking at it now though I guess it shouldn't of!!! , weird.....
P.S.S Actually!, although it compiles it still gives warnings on those lines!
Just rebooted mac... errors gone!!!!!! :-/
Well it compiles!; not sure if it works correctly yet as other things to add.
Why does my method seem horrible?
Can you suggest a nicer way (in straight C) to have a pointer to a table of function pointers?
Cheers though!!
P.S It is strange though. As I wrote this code many years ago for ps1 and it obviously compiled then. Looking at it now though I guess it shouldn't of!!! , weird.....
P.S.S Actually!, although it compiles it still gives warnings on those lines!
Just rebooted mac... errors gone!!!!!! :-/
(Nov 22, 2010 10:59 AM)markhula Wrote: Can you suggest a nicer way (in straight C) to have a pointer to a table of function pointers?
Not sure exactly what you're looking for, but I whipped up a small function pointer example for you in C:
Code:
#include <stdio.h>
#include <stdlib.h>
typedef void (*SpawnFunc)(int myParam1);
typedef void (*HitFunc)(void *obj1, void *obj2);
typedef struct
{
SpawnFunc spawn;
HitFunc hit;
} MyFuncTable;
void testSpawnFunc(int myParam1)
{
printf("testSpawnFunc result: %d\n", myParam1);
}
void testHitFunc(void *obj1, void *obj2)
{
printf("testHitFunc was called.\n");
}
int main (int argc, const char * argv[]) {
MyFuncTable *funcTable = malloc(sizeof(MyFuncTable));
// fill them in
funcTable->spawn = testSpawnFunc;
funcTable->hit = testHitFunc;
// test them out!
funcTable->spawn(123);
funcTable->hit(NULL, NULL);
return 0;
}
Hi there,
Hmmm, yes.
But in my original example suppose you wanted to add another function to HIT_LIST???
i.e. you can't reference hit_func in the SPAWN_DEF...
Cheers
Hmmm, yes.
But in my original example suppose you wanted to add another function to HIT_LIST???
i.e. you can't reference hit_func in the SPAWN_DEF...
Cheers
I am still not quite able to envision what you're looking for. Perhaps something like this you mean?
Code:
#include <stdio.h>
#include <stdlib.h>
enum
{
MY_ASTEROID_HIT_FUNC,
MY_ALIEN_HIT_FUNC,
NUM_HIT_FUNCS
};
typedef void (*SpawnFunc)(int myParam1);
typedef void (*HitFunc)(void *obj1, void *obj2);
typedef struct
{
SpawnFunc spawn;
HitFunc hit[NUM_HIT_FUNCS];
} MyFuncTable;
void testSpawnFunc(int myParam1)
{
printf("testSpawnFunc result: %d\n", myParam1);
}
void testHitFuncAsteroid(void *obj1, void *obj2)
{
printf("testHitFuncAsteroid was called.\n");
}
void testHitFuncAlien(void *obj1, void *obj2)
{
printf("testHitFuncAlien was called.\n");
}
int main (int argc, const char * argv[])
{
MyFuncTable *funcTable = malloc(sizeof(MyFuncTable));
// fill them in
funcTable->spawn = testSpawnFunc;
funcTable->hit[MY_ASTEROID_HIT_FUNC] = testHitFuncAsteroid;
funcTable->hit[MY_ALIEN_HIT_FUNC] = testHitFuncAlien;
// test them out!
funcTable->spawn(123);
funcTable->hit[MY_ASTEROID_HIT_FUNC](NULL, NULL);
funcTable->hit[MY_ALIEN_HIT_FUNC](NULL, NULL);
return 0;
}
Hi again,
Yes, this is what I effectively do.
The problem is assigning the HIT_LIST address (which is in itself a list of function pointers) into the SPAWN_DEF and then being able to access that and index into the HIT_LIST.
Sorry; not a good explanation! :-))
I guess I am asking; how do I get the address of hit_BLAST into my SPAWN_DEF at initialization suiting the definition in SPAWN_DEF below?
void (**hit_list_ptab)(OBJECT_DEF *,OBJECT_DEF *);
Cheers
Yes, this is what I effectively do.
The problem is assigning the HIT_LIST address (which is in itself a list of function pointers) into the SPAWN_DEF and then being able to access that and index into the HIT_LIST.
Sorry; not a good explanation! :-))
I guess I am asking; how do I get the address of hit_BLAST into my SPAWN_DEF at initialization suiting the definition in SPAWN_DEF below?
void (**hit_list_ptab)(OBJECT_DEF *,OBJECT_DEF *);
Cheers
(Nov 22, 2010 12:18 PM)markhula Wrote: Sorry; not a good explanation! :-))
LOL, that's okay, this stuff is hard to communicate at times.
You mean accessing the list of hit function pointers from inside a call to the spawn function, perhaps like this? (mostly same as before, but calling the hit test functions from spawn instead of main, which requires a small cast (which is fine anyway, since it's slightly faster to have a local of the pointer)) <-- BTW, there's more than one way to skin this cat. This is just the way I'd probably do it.
Code:
#include <stdio.h>
#include <stdlib.h>
enum
{
MY_ASTEROID_HIT_FUNC,
MY_ALIEN_HIT_FUNC,
NUM_HIT_FUNCS
};
typedef void (*SpawnFunc)(int myParam1, void *funcTable);
typedef void (*HitFunc)(void *obj1, void *obj2);
typedef struct
{
SpawnFunc spawn;
HitFunc hit[NUM_HIT_FUNCS];
} MyFuncTable;
void testSpawnFunc(int myParam1, void *funcTable)
{
printf("testSpawnFunc result: %d\n", myParam1);
MyFuncTable *func = (MyFuncTable *)funcTable;
func->hit[MY_ASTEROID_HIT_FUNC](NULL, NULL);
func->hit[MY_ALIEN_HIT_FUNC](NULL, NULL);
}
void testHitFuncAsteroid(void *obj1, void *obj2)
{
printf("testHitFuncAsteroid was called.\n");
}
void testHitFuncAlien(void *obj1, void *obj2)
{
printf("testHitFuncAlien was called.\n");
}
int main (int argc, const char * argv[])
{
MyFuncTable *funcTable = malloc(sizeof(MyFuncTable));
// fill them in
funcTable->spawn = testSpawnFunc;
funcTable->hit[MY_ASTEROID_HIT_FUNC] = testHitFuncAsteroid;
funcTable->hit[MY_ALIEN_HIT_FUNC] = testHitFuncAlien;
// test them out!
funcTable->spawn(123, funcTable);
return 0;
}If you wanted to only pass the array of hit functions to spawn, you could do it similarly:
Code:
#include <stdio.h>
#include <stdlib.h>
enum
{
MY_ASTEROID_HIT_FUNC,
MY_ALIEN_HIT_FUNC,
NUM_HIT_FUNCS
};
typedef void (*SpawnFunc)(int myParam1, void *hitFuncs);
typedef void (*HitFunc)(void *obj1, void *obj2);
typedef struct
{
SpawnFunc spawn;
HitFunc hit[NUM_HIT_FUNCS];
} MyFuncTable;
void testSpawnFunc(int myParam1, void *hitFuncs)
{
printf("testSpawnFunc result: %d\n", myParam1);
HitFunc *hitFunc = (HitFunc *)hitFuncs;
hitFunc[MY_ASTEROID_HIT_FUNC](NULL, NULL);
hitFunc[MY_ALIEN_HIT_FUNC](NULL, NULL);
}
void testHitFuncAsteroid(void *obj1, void *obj2)
{
printf("testHitFuncAsteroid was called.\n");
}
void testHitFuncAlien(void *obj1, void *obj2)
{
printf("testHitFuncAlien was called.\n");
}
int main (int argc, const char * argv[])
{
MyFuncTable *funcTable = malloc(sizeof(MyFuncTable));
// fill them in
funcTable->spawn = testSpawnFunc;
funcTable->hit[MY_ASTEROID_HIT_FUNC] = testHitFuncAsteroid;
funcTable->hit[MY_ALIEN_HIT_FUNC] = testHitFuncAlien;
// test them out!
funcTable->spawn(123, funcTable->hit);
return 0;
}
:-)
My problem is at initialisation though.
I don't want to assign my HIT_LIST to my SPAWN_DEF at runtime.
I simply can't work out how/what I cast the hit_blast too within the SPAWN_DEF.
If that makes any sense!! :-))))
Cheers
P.S
(void **)&hit_BLAST, in the spawn_def seems correct but the compiler moans with error: invalid conversion from 'void**' to 'void (**)(OBJECT_DEF*, OBJECT_DEF*)'
It looks like the parameter definition (OBJECT_DEF *,OBJECT_DEF *) is a problem.
My problem is at initialisation though.
I don't want to assign my HIT_LIST to my SPAWN_DEF at runtime.
I simply can't work out how/what I cast the hit_blast too within the SPAWN_DEF.
If that makes any sense!! :-))))
Cheers
P.S
(void **)&hit_BLAST, in the spawn_def seems correct but the compiler moans with error: invalid conversion from 'void**' to 'void (**)(OBJECT_DEF*, OBJECT_DEF*)'
It looks like the parameter definition (OBJECT_DEF *,OBJECT_DEF *) is a problem.
Hmm... Well, in C, you can only assign pointers (which includes function pointers) at runtime. Is there a particular reason you cannot/want-not do it during runtime?
[edit] Hang on a second. I just saw your edit above. I'll take another stab at an example in a bit.
[edit] Hang on a second. I just saw your edit above. I'll take another stab at an example in a bit.
I can't see why the function pointer cannot be assigned at init.
Currently the stuff I am porting does seem to have this in; and whilst I could probably hack in a fix it would be a real pain.
You can assign function pointers at compile time (i.e. init them from their address into a structure); it's just this particular case the compiler chokes on and I can't see why.
Currently the stuff I am porting does seem to have this in; and whilst I could probably hack in a fix it would be a real pain.
You can assign function pointers at compile time (i.e. init them from their address into a structure); it's just this particular case the compiler chokes on and I can't see why.
You mis-understand me (I thought you might :-)))))) )
If I have a func:
void func(DEF *o1,DEF *o2)
You can assign the address of func into a void * function pointer such as &func.
That's what I meant :-)
I am simply trying to do the same; it should work.
To recap (as I feel were going off on a tangent perhaps)
HIT_LIST hit_BLAST[]=
{
&no_hit, // 0
};
SPAWN_DEF def_type_blast=
{
&hit_BLAST, <-- here I want the address of hit_blast function array
};
SPAWN_DEF line for that definition is:
void (**hit_list_ptab)(OBJECT_DEF *,OBJECT_DEF *);
If I have a func:
void func(DEF *o1,DEF *o2)
You can assign the address of func into a void * function pointer such as &func.
That's what I meant :-)
I am simply trying to do the same; it should work.
To recap (as I feel were going off on a tangent perhaps)
HIT_LIST hit_BLAST[]=
{
&no_hit, // 0
};
SPAWN_DEF def_type_blast=
{
&hit_BLAST, <-- here I want the address of hit_blast function array
};
SPAWN_DEF line for that definition is:
void (**hit_list_ptab)(OBJECT_DEF *,OBJECT_DEF *);
Hmm... I know this is incredibly unhelpful, but it isn't obvious to me why what you're trying to do won't work either. 
Long shot: does adding parentheses help? &(hit_BLAST)
You said earlier:
That shouldn't happen. ... and you should never have to reboot your Mac during development. Did you try cleaning your project? (Build->Clean All Targets) We are talking about Xcode though, so weird things do happen from time to time.

Long shot: does adding parentheses help? &(hit_BLAST)
You said earlier:
Quote:Just rebooted mac... errors gone!!!!!! :-/
That shouldn't happen. ... and you should never have to reboot your Mac during development. Did you try cleaning your project? (Build->Clean All Targets) We are talking about Xcode though, so weird things do happen from time to time.
Hurray!
Got it working at last.
Just for the record and also I did appreciate your help.
I made my HIT_LIST a macro and got exactly what I wanted thus:
#define HIT_LIST(name) void( *name[MAX_NUM_TYPES])(OBJECT_DEF *ob1,OBJECT_DEF *ob2)=
allowing me to:
HIT_LIST(hit_BLAST)
{
&no_hit, // 0
&wall_hit,
};
Hopefully you can see what I was trying to do! :-))))))))))
Cheers & thanks again. Not posted that often but it's great to know people are out there trying to help.
Got it working at last.
Just for the record and also I did appreciate your help.
I made my HIT_LIST a macro and got exactly what I wanted thus:
#define HIT_LIST(name) void( *name[MAX_NUM_TYPES])(OBJECT_DEF *ob1,OBJECT_DEF *ob2)=
allowing me to:
HIT_LIST(hit_BLAST)
{
&no_hit, // 0
&wall_hit,
};
Hopefully you can see what I was trying to do! :-))))))))))
Cheers & thanks again. Not posted that often but it's great to know people are out there trying to help.

