Evil function pointer code?

Started by
3 comments, last by SiCrane 19 years, 4 months ago
I know this is pretty much pure evil... But would it work? (assuming that "instance" is of the correct type for the function)

class DummyClass { };
typedef bool (DummyClass::*tHandler)(const Data& d);

template <class T> inline static tHandler CastHandler(bool (T::*hfunc)(const Data& d))
{
    return reinterpret_cast<tHandler>(hfunc);
}

inline static bool CallHandler(void* instance, tHandler hfunc, const Data& d)
{
    return ((*reinterpret_cast<DummyClass*>(instance)).*hfunc)(d);
}

The intended outcome is calling any function in the form of tHandler from any class. The rest of the code would simply hold some tHandler objects and use them through those two functions. It would also ensure that "instance" is of the same type as the function pointer was taken from. I mean, a function of the form:

typedef bool (DummyClass::*tHandler)(const Data& d);
Should still be equivilent to (and callable like) a function of the form

typedef bool (SomeOtherClass::*tHandler)(const Data& d);
Shouldn't it? Would I be right in suggesting that the actual class type that is associated with the function pointer's type dosn't actually do anything useful besides type-safety?
Advertisement
Quote:Original post by Andrew Russell
Would I be right in suggesting that the actual class type that is associated with the function pointer's type dosn't actually do anything useful besides type-safety?


No, this is not good. Member function pointers often include information for properly handling multiple and virtual inheritance situations. Your reinterpret_cast's probably wouldn't handle these cases correctly. In particular, your code would blow up when used on MSVC since they do some evil funky stuff in their member function pointer representations, and the reinterpret_casts on the object pointers probably won't patch the offsets properly to get pointers to the right subobject in MI/VI situations.

You might want to take a look at this article for more about the nitty-gritty involved in mucking with member function pointers in that kind of way.
The classtype is important for the compiler to interpret the 'this' pointer. Basically 'this' points to your classes data (and virtual table). By using these kind of tricks, you're bound to run into problems.
Drat.

OK thanks chaps. I'll have to change to something else most likely (because I think I'll need virtual inheritance). But pretty much for interest sake - would this work ok if the classes were just plain ol' every day classes?


SiCrane: I just opened that article, so I might find the answer in there, but are you saying that a member function pointer is not necessaraly a normal, sizeof()==4, every-day pointer? [edit: so far, the article seems to imply it isn't] [edit again: ok, they arn't]

BTW: thanks for the linkage.

[Edited by - Andrew Russell on December 5, 2004 6:59:48 AM]
It would probably work fine if every class in your program used only single inheritance. But yeah, about half way down the page on that article, there's a table that shows the sizes of different member function pointers under different compilers in different situations, and it's rarely the same size as a normal void pointer.

This topic is closed to new replies.

Advertisement