[inlined] "Terje Slettebų" <[EMAIL PROTECTED]> wrote in message 011401c2a057$f404cf30$60fb5dd5@pc">news:011401c2a057$f404cf30$60fb5dd5@pc... > >From: "Peter Dimov" <[EMAIL PROTECTED]> > > > From: "Johan Nilsson" <[EMAIL PROTECTED]> > > > > > > "Peter Dimov" <[EMAIL PROTECTED]> wrote in message > > > 00bb01c2a046$671b1c20$1d00a8c0@pdimov2">news:00bb01c2a046$671b1c20$1d00a8c0@pdimov2... > > > > From: "Johan Nilsson" <[EMAIL PROTECTED]> > > > > [...] > > > > > template<typename T> > > > > > T* dynamic_void_cast(void* pv) > > > > > { > > > > > struct rtti_obj__ > > > > > { > > > > > virtual ~rtti_obj__() = 0; > > > > > }; > > > > > > > > > > rtti_obj__* pro = static_cast<rtti_obj__*>(pv); > > > > > > > > > > try > > > > > { > > > > > return dynamic_cast<T*>(pro); > > > > > } > > > > > > > > This is not required to work. T's vtable pointer is not guaranteed to > be > > > at > > > > offset 0. > > > > Actually I meant *pv's vtable pointer here. > > > > > But I thought that it _might_ be required to be at the same offset for T > > as > > > for rtti_obj. For that part, IIRC, a vtable isn't required at all, or? > > > > Try it (on several compilers, as some do put the vptr at offset 0.) > > > > struct X { int n; }; > > struct Y: public X { virtual ~Y() {} }; > > > > Y+0: X::n > > Y+4: vptr > > > > rtti_obj__+0: vptr > > I've tested it. Test code: > > --- Start --- > > struct X { int n; }; > struct Y: public X { public: virtual ~Y() {} }; > > int main() > { > Y y; > > Y *yptr=dynamic_void_cast<Y>(&y); > } > > --- End --- > > Here are the results: > > MSVC 6 - vptr at 0 - It works > Intel C++ 7.0 - vptr at 0 - It works > g++ 2.95.3 - vptr _not_ at zero - boom! :) It gives an OS protection error > at the point of dynamic_cast > BCB 6 - vptr _not_ at zero - boom! :) It gives an OS protection error at the > point of dynamic_cast >
I'd appreciate if you could try to (1) use this instead: Y *yptr=dynamic_void_cast<Y>(static_cast<void*>(&y)); and (2) add a virtual destructor to X. What are the results? > Conclusion: Not recommended. :) > > Besides, I can't see the point in testing for bad_cast there, since it uses > T * (not T) in the dynamic_cast, which I think would never throw bad_cast. How true, it was just plain ignorance from my side. > This also means that its signature is different from dynamic_cast, and that > it therefore can't be used for casting references (unlike dynamic_cast). > That was because I couldn't imagine a 'void&', or did I miss something? > In any case, this means it is inherently implementation-dependent and > unsafe. > Basically what I suspected, thanks for taking the time. // Johan _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost