> [std::move silently copies const values, because] If something is const, you can’t move from it by definition. Whoever wrote that definition should have a thing or two to learn from Rust. Different language I know, but it proves that it wasn't needed to cause so much confussion and collectively so much time and performance lost. Also, who writes rules like that and ends the day satisfied with the result? It seems u…
There was no Rust in 2011.
C++ std::move doesn't move anything: A deep dive into Value Categories
101–110 of 220 posts
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#102Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#103Should have be called give(). But naming things correctly is hard, and the C++ committee is known to do a lot of things incorrectly
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#104> So the standard library plays it safe: if your move constructor might throw (because you didn’t mark it noexcept), containers just copy everything instead. That “optimization” you thought you were getting? It’s not happening. This is a bit of a footgun and clang-tidy has a check for it: performance-noexcept-move-constructor. However, I don't think it's enabled by default!
The reason performance-noexcept-move-constructor is not enabled by default is likely because blindly applying noexcept is dangerous if the underlying logic isn't actually exception-free. If you let clang-tidy slap noexcept on a move constructor that does end up throwing (perhaps because it calls into a legacy member or allocates memory internally), the runtime behavior changes from caught exception to std::terminate(…
https://clang.llvm.org/extra/clang-tidy/checks/performance/n... constructor.html
Note that the way std::vector (and other STL containers) require noexcept move constructors for reallocation is by using template matching, and of course any other code might be doing this too, so having a compiler option that forced a constructor (or anything) to have a type signature different than the way it was declared would be a pretty dangerous thing to do since it'd be hard to know what the consequences would be.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#105Earlier quoted context omitted.
What’s the problem? It makes perfect sense to me that a const object cannot be moved from, since it violates the constness. Since constness goes hand in hand with thread safety you really don’t want that violation.
Maybe a compiler error that a const object cannot be “moved”? That would force the programmer to remove the std::move, making it clear that its a copy.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#106Earlier 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.
That's quite inaccurate. It needs to remain destructible, and if the type satisfies things like (move-)assignable/copyable, those still need to work as well. For boxed types, it's likely to set them into some null state, in which case dereferencing them might be ill-formed, but it's a state that is valid for those types anyway.
Thankfully clippy lints do exist here to help if you integrate that tooling
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#107[flagged]
Note that a move constructor that is NOT declared with noexcept is perfectly valid, and will happily be used most of the time (other than where code, such as the STL, is explicitly looking for a noexcept one).
So, for example:
HeavyObject t;
HeavyObject s(std::move(t));
Will cause t to be moved to s.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#108I 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.
Well, no, because CAN take isn't the same as WILL take. Changing something to an rvalue means it'll now match a move constructor, but there is no guarantee a move constructor will be used, even if defined, because you've got classes like std::vector that are picky and are explicitly looking for a noexcept move constructor.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#109Earlier quoted context omitted.
What’s the problem? It makes perfect sense to me that a const object cannot be moved from, since it violates the constness. Since constness goes hand in hand with thread safety you really don’t want that violation.
Maybe a compiler error that a const object cannot be “moved”? That would force the programmer to remove the std::move, making it clear that its a copy.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#110Earlier quoted context omitted.
Maybe a compiler error that a const object cannot be “moved”? That would force the programmer to remove the std::move, making it clear that its a copy.
There are cases where you would not want to reject such code, though. For example, if std::move() is called inside a template function where the type in some instantiations resolves to const T, and the intent is indeed for the value to be copied. If move may in some cases cause a compiler error, then you would need to write specializations that don't call it.