Christopher R Volpe (volpe++at++ash.crd.ge.com)
Mon, 09 Dec 1996 09:48:05 -0500
Well, this just goes to show that you can lead a person to knowledge,
but you cannot make him think. This forced type conversion CAN work
properly, if you're very unlucky, but it cannot be GUARANTEED to work
properly. And this kind of broken coding is never needed. The only time
a function cannot be a static member function is when it needs to access
non-static members, and in order to do this you need a this-pointer to
indicate whose non-static members you want to access.
> Here's a report
> of what I got, for anybody interested...
>
> I have a global function table of member functions,
>
> functype FuncTable[64] = {
> ...
> (functype)MyClass::draw_for_a_specific_attribute_binding;
> ...
> }
I presume "functype" is NOT a pointer-to-member-function type, but is
rather of type pointer-to-ordinary-function, or equivalently,
pointer-to-static-member-function.
>
> And in another member function of the same class, I select a function from
> the function table and call it:
>
> MyClass::Draw(...) {
> ...
> FuncTable[Index](); // note: this function has no argument
> }
This is a catastrophe waiting to happen.
>
> When MyClass::Draw() is called, the calling stack is like:
>
> stack ptr + 0 | THIS pointer |
> stack ptr + 4 | int index |
> ....
This is what I was referring to earlier when I said "if you're unlucky,
it will appear to work, for now".
>
> And after entering function FuncTable[Index](), THE STACK REMAINS THE SAME
> and the this pointer is still on top of stack, which is happily used by
> draw_for_a_specific.. function!
Today, not necessarily tomorrow.
>
> So for it to work two conditions must be satisfied:
> a) the compiler doesn't put any other implicit parameter in calling stack
> frame (e.g. the return address as they normally have in the stack on PCs).
> b) The called function (i.e. functions suffering from the forced type
> conversion) should have any arguments.
>
> Now, the *correct* way to do it is to pass the "this" pointer explicitly.
No, the *correct* way to do it is *not* to invoke functions via function
pointers that do not have the same type as the function they point to.
Specifically, in your case, the *correct* way to do this is to store,
ahead of time, the pointer to the instance you know you want the
callback function to operate on, in a static class member variable. (And
I presume you already know which instance you want to operate on because
you already suggested passing it explicitly.) And then, your
static-member-function callback should examine this static instance
pointer, and invoke the desired non-static-member-function on *it*.
> i.e. for a variable FuncPtr defined and init'd as:
>
> functype FuncPtr = (functype) MyClass::memberFunc;
>
> we should call it as: FuncPtr(objectPtr, other_arguments);
> - sure we are assuming the compiler places the "this" pointer as the 1st arg,
> which is true for the AT&T cfront and sgi's integrated CC.
But not necessarily true in the next release of these compilers.
-Chris
"A little knowledge is a dangerous thing"
--Chris Volpe Phone: (518) 387-7766 GE Corporate R&D Fax: (518) 387-6560 PO Box 8 Email: volpecr++at++crd.ge.com Schenectady, NY 12301 Web: http://www.crd.ge.com/~volpecr ======================================================================= List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/ Submissions: info-performer++at++sgi.com Admin. requests: info-performer-request++at++sgi.com
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:54:06 PDT