gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Casting function pointers with different argument signatures

#62100 - undefined - Sun Nov 27, 2005 12:39 pm

Is it possible to cast a function pointer for a function that takes a char argument into a function pointer that takes no arguments?

What I've got is basically two functions:
Code:
void RBCReadCapacityCommand(UInt8 byte);
SIOWaitForClearToSendWithCallback(void (*clearToSendCallback)(void));


What I'd like to be able to do is this, but I'm not sure if it will result in stack trashing or something equally evil:
Code:
SIOWaitForClearToSendWithCallback(&RBCReadCapacityCommand)


At this time I don't have a unit to try the code on either (I traded my SP for an old shitty computer, STUPIDSTUPIDSTUPID), so for now all I've really got to tell me if my code's even somewhat sane is gcc.

#62106 - wintermute - Sun Nov 27, 2005 2:30 pm

Well, you can, but whether it's advisable or not is something else entirely.

You could use a typedef to cast the pointer to a different signature type like this :-

Code:

typedef void ( * voidFn)(void);

   SIOWaitForClearToSendWithCallback((voidFn)RBCReadCapacityCommand);



The problem is what to do with the invalid parameter that the function will receive. On arm systems you can get away with this since the parameters are passed in registers (the first 4 parameters anyway). On a system where all parameters are passed on the stack you might not.

I'm not 100% certain how the compiler will deal with stack based parameters if you try this. I believe the stack is cleaned by the caller by default which would allow this particular compiler abuse to work but I wouldn't offer any guarantees.

#62111 - undefined - Sun Nov 27, 2005 3:16 pm

That's about what i thought. But I've now come to my senses, and that whole mess has been scrapped for something that actually makes sense :)

#63192 - Joat - Fri Dec 09, 2005 4:13 pm

In future, if you don't have the option of rewriting the function(s), do *not* cast function pointers. On the ARM, it's *probably* safe for functions of fewer than 4 int-sized arguments (for which the ABI defines that r0-r3 are used to pass arguments, and are trashed/must be backed up over a function call, even in void functions), but it's *never* a good idea.

Instead, wrap the function you want to call:

void SomeFunc(int arg);

void SomeFuncVoidWrapper(void) { SomeFunc(0); } // or some other 'null' value

ThirdFuncThatTakesAFP(SomeFuncVoidWrapper)

instead of SomeFunc
_________________
Joat
http://www.bottledlight.com