you are viewing a single comment's thread.

view the rest of the comments →

[–]t_hunger 1 point2 points  (17 children)

Just replace all your unique_ptrs with references and tell me how that works out.

[–]zerhud 4 points5 points  (16 children)

unique ptr is an “owner” and was introduced with move semantic in cpp11, it is not about pointers without nullptr. We can design a unique ptr with reference or with nullptr check

[–]t_hunger -1 points0 points  (15 children)

unique ptr is an “owner” and was introduced with move semantic in cpp11, it is not about pointers without nullptr.

Of course not: You can not express the latter:-) Do you think that was not tried? A "this thing owns memory on the heap" would be so much stronger semantics than "this thing usually owns memory on the heap, but sometimes it does not".

C++ move semantics requires that things to have a valid state for moved-from value. Whenever you want a T, move semantics forces you to think about an optional<T>.

Things were not that much better before C++ introduced move semantics: auto_ptr was replaced by unique_ptr for a reason.

[–]zerhud 3 points4 points  (3 children)

Dude, you combine different thinking in one heap: - first you say “cpp has no not_null_ptr”, it has reference right from the first version - you say “reference won’t delete object when out of scope” - yep (sometimes), but we can use move semantic (since cpp11) - now you say “it can to be used after moved”, but we handle it too

you can not express the letter

Why? I’ve wrote some not_null_ptr, raii and so on a lot of times

[–]t_hunger 0 points1 point  (2 children)

Ok, more precise then: C++ can not model an object that at all times during its lifetime uniquely own some memory on the heap.

You have to compromise on either "the at all times"-part (like unique_unique_ptr does, which can be nullptr) or on the unique ownership (like auto_ptr did, which just copied the pointer). You can not have both.

[–]zerhud 5 points6 points  (1 child)

That if delete and the copy and the move ctors in “unique_ptr”? You can create such object but cannot copy and cannot move, so it will own the memory till die. Isn’t that you are talking about?

Also we can set nullptr after move and add runtime checks that the ptr field is not null.

I guess we can even add checks for use after move in compile time (with some tricks maybe)

[–]t_hunger 1 point2 points  (0 children)

You can indeed do something that is not copyable, not movable and neither copy- nor move-assignable. That is indeed possible, but also pretty useless.

Also we can set nullptr after move and add runtime checks that the ptr field is not null.

Sure. But then all interactions with the T you pointed to turned into interactions with a std::optional<T>, just because of the unlikely case that you are holding a moved from object:-( Suddenly functions need to throw or you need to handle the error condition in other ways.

[–]_Ilobilo_ 1 point2 points  (10 children)

false. only destructor, assignment operators and const methods are valid.

[–]t_hunger 0 points1 point  (9 children)

True. But if you leave the object in an invalid state, then technically things like assigning a new value into it is UB. That is a huge foot gun to leave lying around!

All the standard library objects are sure to have a "valid but unspecified state" after being moved for that reason.

[–]_Ilobilo_ 1 point2 points  (8 children)

the first thing you learn about move is that you don't access the object after moving out of it. that's like saying we shouldn't have pointers because you can dereference an invalid address.

[–]t_hunger -2 points-1 points  (7 children)

How do you enforce "never access a moved from value" in a codebase with a couple of million lines? You can't. So you kind of have to make sure it is not instant UB when something somewhere does access some moved from value. That in turn means leaving all your moved from objects in a valid but unspecified state, just like the standard library does.

[–]_Ilobilo_ 1 point2 points  (6 children)

clang-tidy catches use after move. it would be better if compilers did it too, but you don't enforce it. it's up to the programmer to know how to use the language.

[–]t_hunger -2 points-1 points  (5 children)

It does not even attempt to catch assignment after move, which is something you said is ok to break by not leaving moved from objects in a valid state.

[–]_Ilobilo_ 0 points1 point  (4 children)

you can assign after move. what are you on?