Boost logo

Boost Users :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-02-06 08:44:53


Konstantin Baumann wrote:
> For performance reasons I would like to see something like the
> following conversion operators in shared_ptr<T>:
>
> template<class T>
> class shared_ptr {
> public:
> ...
> template<class S>
> operator shared_ptr<S>&() throw() {
> BOOST_STATIC_ASSERT(T* is convertible to S*);
> return reinterpret_cast<shared_ptr<S>&>(*this);
> }

[...]

Right. ;-)

There are several things wrong with this code.

First, T* convertible to S* does not imply that the memory layout of T* and
S* is the same. Specifically, T* and void* may have different
representations and sizes. reinterpret_casting a T* to a void*& is not
portable.

Second, assuming that memory layout is not an issue, there is the classic
"nuclear submarine in a car park" type system hole.

void f(shared_ptr<void> & p) { p.reset(new float); }

int main()
{
    shared_ptr<int> q(new int); // see int, think 'car'
    f(q);
    // oops, q now holds a float (nuke sub)
}

Third, the conversion between T* and S* may change the value of the pointer.
In multiple inheritance scenarios (and, depending on the object model, even
in some single inheritance cases) an offset is added to T*. With virtual
inheritance, it's even more complicated; typically the vtable of the source
object of type T is accessed to retrieve the offset to the S virtual base.

In short, even though it is no coincidence at all that a shared_ptr<X> is
often layout compatible and (somewhat safely) reinterpret_cast'able to
shared_ptr<Y>, you need to accept the responsibility for the cast yourself.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net