Replacing auto_ptr in VC++ 8

std::auto_ptr is broken in VC++ 8 (which is what we use at work). My main gripe with it is that it allows auto_ptr<T> x = new T();, which of course leads to horrible crashes, while being simple to do by mistake.

From an answer to another question here on stackoverflow:

Note that the implementation of std::auto_ptr in Visual Studio 2005 is horribly broken. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98871 http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842

I want to use

But since std::auto_ptr is broken for me, I wonder what would be the best approach:


Update: Here is what I did: I copied the aforementioned auto_ptr implementation by Rani Sharoni. From here.

Did some minor tests:

class T
{
public:
    T() {
        OutputDebugStringA("T\n");
    };
    ~T() {
        OutputDebugStringA("~T\n");
    };
};

{
    fix::auto_ptr<T> x(new T); // This just works.
}
{
    fix::auto_ptr<T> x = (new T); // Doesn't compile. Great!
}
{
    fix::auto_ptr<T> x = fix::auto_ptr<T>(new T); // Transfer of ownership works also.
}

Of course these tests are by no means exhaustive and you shouldn't trust them. Implementing an exception safe templated class is hairy business. At least this works better than the built in one.

Note: I don't know if I'm allowed to use this implementation yet, with respect to copyright. I have emailed Rani and I'm waiting for a reply. I'll update this post when I know more. Permission is granted for everyone to use Rani Sharoni's auto_ptr implementation as you wish.

Thank you for all your replies.

Upvotes: 9

Views: 2189

Answers (7)

Pavel Minaev
Pavel Minaev

Reputation: 101595

Not an answer, but for general interest of anyone for whom these bugs are relevant. There's one more related bug with VC8's auto_ptr, which has to do with implicit upcasts. It's probably the most evil of the bunch, because other bugs just let you compile code that is otherwise illegal according to Standard without failing, but at least compliant code works fine. With this bug, the code that is actually compliant does not work properly.

The problem is this. Standard specifies auto_ptr constructors and conversion operators in such a way that they support implicit upcasting of auto_ptrs, just as with normal pointers. However, VC8 implementation of that does a reinterpret_cast rather than a static_cast there. Naturally, not only this is U.B. by the letter of the standard, but it also breaks with multiple base classes and/or virtual inheritance. Here's an example of legal code broken by this:

struct Base1 { int x; };
struct Base2 { int y; };
struct Derived : Base1, Base2 {};

std::auto_ptr<Derived> createDerived()
{
  return std::auto_ptr<Derived>(new Derived);
}

std::auto_ptr<Base2> base2(createDerived());

At one of my past jobs, when we ran into this problem in production, we ended up simply patching the headers ourselves (it's a trivial 2-line fix).

Upvotes: 0

Maciek
Maciek

Reputation: 19893

As far as I recall, wasn't it :

auto_ptr<T> x = auto_ptr<T>(new T()); ??

Upvotes: 0

peterchen
peterchen

Reputation: 41106

Move to boost smart pointers.

In the meantime, you may want to extract a working auto_ptr implementation from an old / another STL, so you have working code.

I believe that auto_ptr semantics are fundamentally broken - it saves typing, but the interface actually is not simpler: you still have to track which instance is the current owner and make sure the owner leaves last.

unique-ptr "fixes" that, by making release not only give up ownership, but also setting the RHS to null. It is the closest replacement for auto-ptr, but with its different semantics it is not a drop-in replacement.

There's an introductory article to boost smart pointers, by, ahem, me.

Upvotes: 7

Scott Langham
Scott Langham

Reputation: 60351

Use a unique_ptr. I think these were introduced to be a better auto_ptr.

http://www.boost.org/doc/libs/1_35_0/doc/html/interprocess/interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.unique_ptr

In fact, I'm led to believe auto_ptr may be deprecated in favour of it:

http://objectmix.com/c/113487-std-auto_ptr-deprecated.html

Upvotes: 2

OJ.
OJ.

Reputation: 29401

Have you considered using STLPort?

Upvotes: 3

MP24
MP24

Reputation: 3200

Use boost::shared_ptr/boost::scoped_ptr. It will be the preferred smart pointer in upcoming C++ standards (is in TR1 already).

Edit: Please find a related discussion here: Idiomatic use of std::auto_ptr or only use shared_ptr?

Upvotes: 0

Loki Astari
Loki Astari

Reputation: 264481

Why do you think std::auto_ptr<> is broken.

I would have though that somthing as bad as that would have been reported to the standards comitte!

Do you mean that you need to:

std::auto_ptr<T>   x(new T);  // Use the explicit constructor.

Upvotes: 1

Related Questions