Live data from Hacker News

C++ std::move doesn't move anything: A deep dive into Value Categories

0xghost.dev

11–20 of 220 posts

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#11

I don’t think this is particularly insightful, as move semantics and r-values are higher level language semantics, nothing more and nothing less. Rust’s borrow checker doesn’t actually borrow anything either, it’s operating on a similar level of abstraction.

> Rust’s borrow checker doesn’t actually borrow anything either

Why would it? It's called the borrow checker, not the borrower. So it checks that your borrows are valid.

std::move looks and feels like a function, but it doesn't do what it says, it makes objects movable but does never moves them (that's up to whatever is using the value afterwards). If you want something similar in Rust, Pin is a much better candidate.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#12
post #2

I always understood move as moving ownership, so it's not a misnomer. > std::move is like putting a sign on your object “I’m done with this, you can take its stuff.” Which exactly is moving ownership.

Std move doesn’t move ownership. It simply casts into something that could have its ownership taken. Whether or not that actually happens is impossible to identify statically and the value after ownership is consumed is unspecified - sometimes it’s UB to access the value again, sometimes it’s not.

It is absolutely knowable statically if ownership will be taken. It's not necessarily very easy to do so, but the decision is 100% up to the compiler, as part of overload resolution and optimization choices (like the NRVO analysis that the article mentions). Since ownership is an inherently static concept, it doesn't even make sense to think about "runtime ownership".

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#13
post #6

Earlier quoted context omitted.

Std move doesn’t move ownership. It simply casts into something that could have its ownership taken. Whether or not that actually happens is impossible to identify statically and the value after ownership is consumed is unspecified - sometimes it’s UB to access the value again, sometimes it’s not.

May be disown would be more descriptive, but the point is that it's intended for transferring of ownership versus copying data.

> it's intended for transferring of ownership versus copying data.

It's intended for transferring ownership, but what it actually does is mark the value as transferrable, whether or not the value is actually transferred is up to the callee.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#14

Earlier quoted context omitted.

Std move doesn’t move ownership. It simply casts into something that could have its ownership taken. Whether or not that actually happens is impossible to identify statically and the value after ownership is consumed is unspecified - sometimes it’s UB to access the value again, sometimes it’s not.

It is absolutely knowable statically if ownership will be taken. It's not necessarily very easy to do so, but the decision is 100% up to the compiler, as part of overload resolution and optimization choices (like the NRVO analysis that the article mentions). Since ownership is an inherently static concept, it doesn't even make sense to think about "runtime ownership".

My function can choose to move or not to move from an object based on io input.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#15
post #2

I always understood move as moving ownership, so it's not a misnomer. > std::move is like putting a sign on your object “I’m done with this, you can take its stuff.” Which exactly is moving ownership.

std::move itself doesn't move ownership, though. It allows the compiler to transfer ownership to the receiver of the value, but it doesn't force it in any way. This is important, because it means YOU may still be the owner of a value even after you called std::move on it.

Not to mention, ownership in C++ is not entirely lost with moves in the traditional sense. For example, your code still has to destruct the object even if you did move it to somewhere else.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#16
post #14

Earlier quoted context omitted.

It is absolutely knowable statically if ownership will be taken. It's not necessarily very easy to do so, but the decision is 100% up to the compiler, as part of overload resolution and optimization choices (like the NRVO analysis that the article mentions). Since ownership is an inherently static concept, it doesn't even make sense to think about "runtime ownership".

My function can choose to move or not to move from an object based on io input.

Can you show an example of what you mean?

My claim is that, if I call `foo(std::move(myObj))`, it is statically knowable if `foo` receives a copy of `myObj` or whether it is moved to it. Of course, `foo` can choose to further copy or move the data it receives, but it can't choose later on if it's copied or not.

Now, if I give `foo` a pointer to myObj, it could of course choose to copy or move from it later and based on runtime info - but this is not the discussion we are having, and `std::move` is not involved from my side at all.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#17
post #3
post #2

I always understood move as moving ownership, so it's not a misnomer. > std::move is like putting a sign on your object “I’m done with this, you can take its stuff.” Which exactly is moving ownership.

Personally I see std::move more like removing ownership because it’s not explicit from its call where the ownership is transferred.

Even that is a bit suspect, because ownership may well remain with you even after the call, so it's not really removed.

For example, this is perfectly valid C++, and it is guaranteed to have no issue:

  std::string abc = "abc";
  std::move(abc); //doesn't remove ownership or do anything really
  std::print(abc); //guaranteed to print "abc"

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#19
post #14

Earlier quoted context omitted.

My function can choose to move or not to move from an object based on io input.

Can you show an example of what you mean? My claim is that, if I call `foo(std::move(myObj))`, it is statically knowable if `foo` receives a copy of `myObj` or whether it is moved to it. Of course, `foo` can choose to further copy or move the data it receives, but it can't choose later on if it's copied or not. Now, if I give `foo` a pointer to myObj, it could of course choose to copy or move from it later and based…

> Can you show an example of what you mean?

    void foo(std::unique_ptr&& p) {
        std::random_device rdev {};
        auto dist = std::uniform_int_distribution(0, 1);
        if (dist(rdev)) {
            auto pp = std::move(p);
        }
    }

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#20
post #18

Should have be called give(). But naming things correctly is hard, and the C++ committee is known to do a lot of things incorrectly

That has about the same issue: like std::move it doesn't really explain that the receiver decides.
Post reply on HN