top | item 18779725

(no title)

asdkfjasl | 7 years ago

unique_ptr is super useful for documenting the point in the code that owns a given object, and for providing some compile time protection against multiple deletions. (If you never write delete and only use unique_ptr, you have to do a relatively foolish thing to get double deletions.)

discuss

order

4bpp|7 years ago

I've written some heap-heavy code and never used unique_ptr, but I don't remember ever causing a double deletion. What's a pattern which you figure makes one prone to doing that? (On that basis, I'm a little inclined to suspect that it may be more of an issue for programmers who came from a deeply memory-managed language like Java and therefore don't build mental models to keep track until when a given allocation is needed.)

(I have of course produced my share of memory leaks - praise be to valgrind - but they were all in scenarios where unique_ptr would have been too restrictive (without a Rust-style complete reconsideration of the code's ownership structure).)

oscargrouch|7 years ago

One thing i like about using std::unique_ptr now that we have and use std::move() is to annotate in the API when you want to own the heap object being passed or to say that the api consumer should own the reference.

I get that if you just use it for usual the owning class, it doesnt provide that much, but it annotates lifetime, and its pretty cool when you get used to it.

if you see this:

    class X {
     Y* y;
    };
Does X owns Y? or is owned by Z and X is just using it?

    class X {
     std::unique_ptr<Y> y;
    };
Now you know for sure X owns y.

    class X {
      std::unique_ptr<Y> CreateY();
      Y* CreateY();
    };
Look how in the first example you know that X wont retain a copy of Y, and the caller will be considered the owner of the heap..

Now in the second example you are not sure if X retain and will handle the deletion of Y, and you should use Y, while in the first example its perfectly clear the api intention.

the same here:

    void AddY(std::unique_ptr<Y> y)
    void AddY(Y* y)
in the first you are aware you are passing the ownership of Y, in the second you wont be sure if you still need to handle the deletion yourself.

Before std::move() i get it, but after you can pass things by moving them, i dont get it why anyone would not like to use this.

For me this is basically the "lifetime annotation" feature, only that it is by convention, and not enforced by the compiler. Unlike others these are the reasons why i dont feel the urge to jump the Rust bandwagon, and prefer to use things like Swift when i need a more "chill" environment to work, as i didnt feel more productive in Rust than in C++, while with Swift it happened and it also has a pretty good story perfomance wise.

I prefer to mix C++/Swift as my perfect duo, than try to make it all fit in one language, as this always lead to frustation and a lot of headaches.

summerlight|7 years ago

If code is completely under your control, then it's okay. But from my experience, these kinds of errors frequently stem from large code bases without a clear ownership. Think about a case that hundreds of people are working on the same code base. You may not understand 99% of code, and probably don't even want to understand all the horrors written by other programmers.

In fact, I have seen a number of horrific instances that someone decided to write clever tricks with object lifetime which leads to production crash and no one really understand (or even bother) what's going on there. The only way to deal with such code is looking into its implementation, probably for a week or two. And found that the original author has left the company.

In these cases, static type annotation helps a lot by serving as a formal contract. To reason about object lifetime, you don't need to dig into the implementation; all you need is looking into variable's type signature. Same thing can be applied to types other than those related to object lifetime.

asdkfjasl|7 years ago

Some people are robots and never write errors. I and most C++ programmers are not in that category.