You read things like this and, first, you're reminded of Sideshow Bob [1] and it puts Rust concepts in context, namely: 1. Move semantics are to handle ownership. Ownership is a first-class concept in Rust. This is why; 2. C++ smart pointers (eg std::unique_ptr ) are likewise to handle ownership and incur a runtime cost where in Rust they are handled by the compiler with no runtime cost. Yes you can "cheat" (eg std::…
C++ std::move doesn't move anything: A deep dive into Value Categories
121–130 of 220 posts
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#122Before move semantics the HeavyObject problem was solved in most cases by specializing std::swap for each container. The design lesson I draw from this is that pursing a 100% general solution to a real problem is often worse than accepting a crude solution which covers the most important cases.
you want a well working general solution which works well (most of the time for most of the "generic code" (i.e. good defaults for the default use-case).
and then add escape hatches for micro-optimizations, micro-control etc.
C++ on the other hand was deeply rooted designed with micro optimizations and micro control first.
"Generic solutions" where then tried to be added on top, but not by changing a badly working abstraction/design but by adding more abstraction layers and complexity on top. And with a high requirements for back/forward compatibility, not just with the language but ton of different tooling. That this isn't playing out well is kinda not really surprising IMHO. I mean adding more abstraction layers instead of fixing existing abstraction layers rarely plays out well (1) especially if the things you add are pretty leaky abstractions.
-----
(1): In context of them archiving overall the same goal with just different details and no clear boundaries. Layering very different kind of layers is normal and does make sense in a lot of situations. Just what C++ does is like layering "a generic system programming language" (modern C++) on top of "a generic system programming language" (old C++) without clear boundaries.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#123Regarding mistake 1: return std::move(local_var), it is worth clarifying why this is technically a pessimization beyond just breaking NRVO. It comes down to the change in C++17 regarding prvalues. > Pre-C++17, a prvalue was a temporary object. > Post-C++17, a prvalue is an initializer. It has no identity and occupies no storage until it is materialized.
In C++17 if you do return std::move(local_variable) it will do exactly what you asked for and move the local variable to the return value, which with copy elision means directly to the caller's variable.
So, return std::move(local_variable) is only preventing NRVO, it's not preventing a move (even though you shouldn't be asking for a move, because move is not the most efficient way).
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#124About 28 years ago, I figured out that I’m just not smart enough to use C++. There are so many foot guns and so much rampant complexity that I can’t keep it all straight. I crave simplicity and it always felt like C++ craved the opposite.
Systems programming in the large is hard, owning the category for decades harder still. Even languages that have tried to fast-follow and disrupt C++ end up looking a lot like C++. There is an irreducible complexity.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#125Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#126About 28 years ago, I figured out that I’m just not smart enough to use C++. There are so many foot guns and so much rampant complexity that I can’t keep it all straight. I crave simplicity and it always felt like C++ craved the opposite.
I understand the individual rationales of C++ things but I lost the faith on the whole thing.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#127> This code works. It compiles. It runs. But depending on how you’ve implemented your types, it might be performing thousands of expensive copy operations instead of cheap moves without you realizing it. I've spent the last two decades in the .net platform. But for a decade or so before that I was a C++/Unix dev. I remember old style "C with classes" C++ as being fairly small and elegant, and approximately as easy to…
it (C++) never really was that
but it was possible to use it "as if it where that" (kinda, e.g. there is code which is valid in C but UB in C++)
I mean there where also times where books which told you that in C everything "is just bits in memory" where popular/believed/beloved, even through that never really was true outside of some very specific cases (all of CPU without caches, only in order execution, single core, a mostly non-optimizing compiler, and other requirements). It was just that the chance to run into issues was much less likely if you go ~20+ years back into the past so you could kinda use it like that (at some risk, especially wrt. forward compatibility).
Today you find ton of material even about obscure features, complications, hidden food guns, etc. so things do look/feel far more overwhelming IMHO.
That modern C++ is a bit like a different language glued on top of old C++ doesn't exactly help either.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#128About 28 years ago, I figured out that I’m just not smart enough to use C++. There are so many foot guns and so much rampant complexity that I can’t keep it all straight. I crave simplicity and it always felt like C++ craved the opposite.
For instance, if you want to avoid unnecessary copy operations when returning a string, just return it in variable that you pass by reference (eg. void doSomething(string& str);) likewise avoid the vector class making unnecessary copies, simply by creating the objects on the heap and use a vector of pointers instead of values. It's a bit more ugly, but it works, and you don't need to read a 24 page blog to understand all the corner cases where it can go wrong. modern c++ is all about syntactic suger.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#129and later:
> Specifically, that ‘sign’ (the rvalue reference type) tells the compiler to select the Move Constructor instead of the Copy Constructor.
This is the best conceptual definition of what `std::move` is. I feel that is how every book should explain these concepts in C++ because its not a trivial language to get into for programmers who have worked with differently opiniated languages like python and java.
If you read Effective Modern C++ right Item 23 on this, it takes quite a bit to figure out what its really for.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#130Earlier quoted context omitted.
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(…
I would argue performance-noexcept-move-constructor should always be on. Move constructors should almost always be noexcept since they typically just move pointers around and don't do allocations normally.