Gerrit Voss wrote:
> Hi,
> 
> On Tue, 2005-08-02 at 16:55 -0500, Patrick Hartling wrote:
> 
>>After a long, frustrating afternoon of debugging, I have discovered
>>something peculiar when trying to use a member function from a class with
>>multiple bases as the functor for OSG::traverse(). I use
>>OSG::osgTypedMethodFunctor1ObjPtrCPtrRef<...>() to create the functor that
>>is handed off to OSG::traverse(), and up until now this has worked fine.
>>When using Visual C++ 7.1 and a class that uses multiple inheritance,
>>however, the OSG::FunctorBase<T>::_flags data member is trashed in the call
>>to OSG::TypedStoredObjectFunctorBase<...>::setMethod() because the storage
>>for the OSG::FunctorBase<T>::_data2 member is not large enough. Only four
>>bytes are allocated, but eight are required.
>>
>>The tricky thing is that this only appears to happen with Visual C++ 7.1 and
>>a class that uses multiple inheritance. The attached program demonstrates
>>the behavior. When compiled with Visual C++ 7.1, sizeof(&A::f) returns 4
>>whereas sizeof(&B::f) returns 8. With GCC 3.4 (tested on Fedora Core 3) and
>>4.0 (tested on Mac OS X 10.4.2), both return 8.
>>
>>It is probably possible for me to work around this behavior by passing an
>>alternate type for the SizeTraitsT template parameter to
>>OSG::FunctorBase<T>, though I have not tried doing so yet. I do not know if
>>there is a solution that OpenSG can use to account for this case, but if I
>>come up with one, I will submit a patch.
> 
> 
> there should be an easy fix, basically one has to change the way the
> sizes are calculated.
> 
> Right now OpenSG only takes the maximum of either function or method
> pointer with no inheritance. Checking the size of method functors with
> multiple inheritance should not be a too big problem.
> 
> could you try to use if the following helps (I don't have windows to
> try)
> 
> struct DefaultFunctorSizeTraits
> {
>     struct Base  {};
>     
>     struct Base1 {};
> 
>     struct Derived : public Base, public Base1 {};
> 
>     typedef 
>         void (                          *FuncPointerT        )(void *);
>     typedef 
>         void (DefaultFunctorSizeTraits::*InstanceFuncPointerT)(void *);
> 
>     typedef 
>         void (Derived                 ::*MethodFuncPointerT)(void *);
> 
>     enum SizesE
>     { 
>         _uiFuncPointerSize1 = osgStaticMax<sizeof(FuncPointerT),
>                                           sizeof(InstanceFuncPointerT)
> 
>>::iMax,
> 
> 
>         _uiFuncPointerSize = osgStaticMax<_uiFuncPointerSize1,
>                                           sizeof(MethodFuncPointerT)
> 
>>::iMax,
> 
> 
>         _uiObjectSize      = 64
>     };
> };

Gerrit,

I completely dropped the ball on this one. I think I ended up going a
different route with my traversal callbacks and forgot to test your code. It
does work with Visual C++ 7.1, and since I am running into a similar problem
again, it would be great to see this change checked in.

The circumstances with this new problem are similar but different. This
time, the class with the member functions used for traversal does not use
multiple inheritance, but the member function pointer size is still 8. I
don't yet know why that is the case, but with your change, the memory
allocated for the pointer is always 8 bytes on Visual C++ 7.1. As such, it
fixes my new problem right up.

 -Patrick


-- 
Patrick L. Hartling                    | VP Engineering, Infiscape Corp.
PGP: http://tinyurl.com/2msw3          | http://www.infiscape.com/

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to