Live data from Hacker News

Move, simply

herbsutter.com

41–50 of 96 posts

Re: Move, simply

#41
post #40

> (Other not-yet-standard proposals to go further in this direction include ones with names like “relocatable” and “destructive move,” but those aren’t standard yet so it’s premature to talk about them.) Herb Sutter seems to be burying the lede here. My read on Herb Sutter's post is that the current typical methodology (as represented by the IndirectInt example), is buggy as per the current specification. What we all…

It's going to be amazing when they add a true "destructive move" and everyone has to learn about the different kinds of moves and when to use which one. > a "moved-from" C++ object is NOT in any special state, like it is in some other popular languages. In practice it is; it's in a special state of "satisfies class invariants but otherwise undefined". From the developer's point of view this is very little different f…

> It's going to be amazing when they add a true "destructive move" and everyone has to learn about the different kinds of moves and when to use which one.

No different than when they added move the first time in C++11 and everybody had to learn the difference between copy and move. No different than Rust programmers learning the difference between Rust's move and C++'s move.

Stuff changes over time. In this case, I think it is warranted. The C++11 move is useful in many cases, but not useful enough for how many programmers use unique_ptr stuff. Adding that little bit of extra state for the compiler to track might be helpful.

> In practice it is;

That's the mismatch between C++ Programmers and C++ Language. In effect, C++ Programmers want destructive moves and are currently coding their move statements AS IF they were destructive moves.

Herb Sutter is careful to choose the auto_ptr example. Because he's basically saying that unique_ptr is making the same mistake auto_ptr made years ago... the move semantics are subtly different and need to be changed and/or updated.

Re: Move, simply

#42

I found it's much easier to understand the concepts behind move operations if you write an object that implemented move semantics by itself. class Object { int* data = new int[32]; void move_into( Object& object ) { object.data = data; data = nullptr; } ~Object() { delete[] data; } } Object a; Object b; a.move_into( b ); I think much of the confusion arises from wondering where is the allocation for int* data located…

I appreciate it's just an example, but it should be mentioned that this is a really bad class. If you write a custom destructor, you must also specify the move/copy constructors and move/assignment operators. Otherwise, the same data pointer will be deleted twice if the object is ever copied.

Yes I know this of course but it seemed that leaving things out is faster and people can know it's just a toy.

Re: Move, simply

#43
post #40

Earlier quoted context omitted.

It's going to be amazing when they add a true "destructive move" and everyone has to learn about the different kinds of moves and when to use which one. > a "moved-from" C++ object is NOT in any special state, like it is in some other popular languages. In practice it is; it's in a special state of "satisfies class invariants but otherwise undefined". From the developer's point of view this is very little different f…

> It's going to be amazing when they add a true "destructive move" and everyone has to learn about the different kinds of moves and when to use which one. No different than when they added move the first time in C++11 and everybody had to learn the difference between copy and move. No different than Rust programmers learning the difference between Rust's move and C++'s move. Stuff changes over time. In this case, I t…

> No different than when they added move the first time in C++11 and everybody had to learn the difference between copy and move.

Yes, it's not the first time the cognitive load of C++ has increased.

> No different than Rust programmers learning the difference between Rust's move and C++'s move.

Learning concepts in a new language doesn't increase cognitive load in the same way. In C++ you will have to decide which kind of move to use in any given situation, and deal with code using multiple kinds of moves. Learning Rust doesn't create such issues.

> Adding that little bit of extra state for the compiler to track might be helpful.

It'll be interesting to see how that goes. In Rust the compiler ensures safe code can't access a moved-out-of object, but that depends on Rust's strong aliasing guarantees. In C++ I guess accessing a moved-out-of object will have to be a new kind of undefined behavior, creating new classes of bugs and requiring new sanitizers and approximate static checkers to be implemented.

Re: Move, simply

#44

Move semantics are a great addition to C++, but off the top of my head, there are two warts: - C++ moves are not destructive (as compared to move semantics in Rust). This means that types must arrange for a valid "moved-from" state. This isn't a huge issue if the type has a natural sentinel value, but not all types have one and I often end up wrapping class members in std::optional to arrange for one. Frankly, this i…

With regard to the rvalue vs perfect forwarding references comment: there's actually no special syntactic difference between the two. The reason forwarding works is because in

    template 
    void do_thing(T&&)
T will (with an rvalue) match the actual type, whereas with an lvalue it will match a reference to the type (i.e., you're moving a reference). This is what allows something like std::forward to be in the standard library and implemented in the language itself (without accessing any compiler builtins). That's not to say what's going on there is obvious nor really easy to reason about. It's more a hack that happens to work, like much of the templating ecosystem.

Re: Move, simply

#46

> (Other not-yet-standard proposals to go further in this direction include ones with names like “relocatable” and “destructive move,” but those aren’t standard yet so it’s premature to talk about them.) Herb Sutter seems to be burying the lede here. My read on Herb Sutter's post is that the current typical methodology (as represented by the IndirectInt example), is buggy as per the current specification. What we all…

So, what do you propose std::move should do?

Initializing the ‘source’ int to zero seems the only reasonable option, but it would hurt performance.

Also, what about std::move in general? If T has a destructor, should that call it on the original? Currently, deciding whether that (or doing its equivalent) is a good idea is up to the implementer of std::move. I don’t see how the compiler could make that decision without sacrificing performance in some cases.

I think that, if you want the compiler to enforce destruction of moved-from values, you also should want the compiler to zero out (or equivalent) all destructed values.

Re: Move, simply

#47
post #46

> (Other not-yet-standard proposals to go further in this direction include ones with names like “relocatable” and “destructive move,” but those aren’t standard yet so it’s premature to talk about them.) Herb Sutter seems to be burying the lede here. My read on Herb Sutter's post is that the current typical methodology (as represented by the IndirectInt example), is buggy as per the current specification. What we all…

So, what do you propose std::move should do? Initializing the ‘source’ int to zero seems the only reasonable option, but it would hurt performance. Also, what about std::move in general? If T has a destructor, should that call it on the original? Currently, deciding whether that (or doing its equivalent) is a good idea is up to the implementer of std::move . I don’t see how the compiler could make that decision witho…

std::move has been part of the language for 9 years. It is no longer reasonable to change std::move.

To satisfy the programmer, there probably should be a std::dmove(x), which would be a compiler-enforced notation that would make use of x illegal after the use of std::dmove.

std::dmove(x) would be implemented as std::move, followed by a destructor, and then the compiler removes variable x from the scope. Pointers and references to that variable will have undefined behavior if they are used (compiler may find it reasonable to recycle x's memory location to another variable)

------

std::move remains the same. There's no performance benefit, or even code-logic benefit, to zeroing out integers. For example, an integer may be a denominator, dividand, modulus, or multiplier. In these cases, "zeroing out" to "x = 1" makes more sense than "x=0".

Having a compiler enforced "zero" of "x=0" is arbitrary and doesn't help anybody. Its better to let the integers remain the same value they used to be.

Re: Move, simply

#49
post #17

C++ “move” semantics are simple, but they are still widely misunderstood. No, they aren't simple and the fact that are still widely misunderstood is basically proof of that. Maybe, just maybe, it has something to do with stuffing rvalue references, perfect forwarding and the whole universal-references-template-clusterfuck into one and the same syntax. [1] The default compiler-generated move can leave behind a null sp…

> still widely misunderstood is basically proof of that.

How much better the world would be if software developers started making judgements based on empirical evidence instead of rhetoric and navel gazing...

To paraphrase the old bit:

If an idiot misuses your software in the morning, you have a user who's an idiot. If idiots misuse your software all day, you're the idiot.

Re: Move, simply

#50

> C++ “move” semantics are simple , but they are still widely misunderstood. To use a quote from one of my favorite movies: you keep using that word. it doesn't mean what you think it means! Articles such as this one remind of how C++ is such a design-by-committee language. Watching it evolve is like watching a 100 chefs in a kitchen working on a single dish, where everyone wants the dish to taste the way they like i…

I don't think design-by-committee is the problem, it's more the makeup of the committee. They're all mostly academics, compiler experts, c++ experts and trying to chase some sort of purity. The committee needs someone that represents the mere mortals.
Post reply on HN