lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> From: Vincent Penquerc'h
>
> Could you elaborate a little on what subtle bugs not casting could
> introduce please ?

Sure.

#include <iostream.h>
class Base1 { public: int b1; };
class Base2 { public: int b2; };
class Derived : public Base1, public Base2 {};
void main( void )
    {
    Derived derived;
    void * pDerived = & derived;
    void * pBase1 = ( Base1 * ) & derived;
    void * pBase2 = ( Base2 * ) & derived;
    cout << pDerived << endl << pBase1 << endl << pBase2 << endl;
    }

On my system, this outputs:

0x0012FF6C
0x0012FF6C
0x0012FF70

Note that pBase2 != pDerived.  Therefore, if you do this:

lua_pushuserdata( & derived );

The value of the userdata is 0x0012FF6C.  If your lua script passes that
value back, and you cast it directly to Base2:

Base2 * pBase2 = ( Base2 * ) lua_getuserdata(lua_getparam(1));

pBase2 == 0x0012FF6C, when it should == 0x0012FF70.  Your code would crash.

A similar problem occurs if you do this:

Base2 * pBase2 = & derived;
lua_pushuserdata( pBase2 );

...

Derived * pDerived = (Derived *) lua_getuserdata(lua_getparam(1));

In this case, pDerived == 0x12FF70 when it should == 0x12FF6C.

The way to avoid both problems is to always perform an explicit cast to a
common base class when you push userdata, and always cast back to that base
class when you recover the userdata.

Regards,
ashley