Earlier quoted context omitted.
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.
eh, depends. for instance think about a small_vector or small_string
C++ std::move doesn't move anything: A deep dive into Value Categories
131–140 of 220 posts
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#132About 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.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#133Earlier quoted context omitted.
> 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 candida…
Sure, but from the perspective of the code that has the move() its good to assume the value is moved at that call, which I guess was the intention of picking the name.
std::move tells the devs and the compiler that you _intend_ the value to be moved
sadly that isn't reflected well in it's implementation as it will "silently" degrade even if it isn't a "move" (1)
A `std::move` which fails to compile if it can't be a move(1) it would not have this issues.
But it has other issues, mainly wrt. library design especially related to templates/generics, which probably(?) need a `std::move` which works like the current one. I think someone else in this comment section already argued that one issue with modern C++ is too much focusing on the complicated/template/const library design by experts case compared to the "day to day" usage by non experts.
(1): There is a bit of gray area in what in rust would be Copy types, for simplicity we can ignore them in this hypothetical argument about an alternative std::move design.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#134Earlier quoted context omitted.
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.
I hear this a lot, but I don’t really understand how this manifests in language complexity like the stuff in TFA in practice. Like, I can understand how systems programming requiring programmers to think about questions like “how can I proceed if allocation fails? How does this code work in an embedded context with no heap?” is hard and irreducible. But I can’t understand why a language’s choice to impose complex rul…
Programmer here for 30 years in C/C++. It is true that C++ has become a more complex language after rvalue references were introduced, but you have to understand the rationale behind C++: a language suitable for large scale systems programming with *ZERO OVERHEAD*.
The language complexity especially rvalue references was to reduce overhead. Pre-C++-11, there were many code patterns that involved constructing temporaries and destroying them immediately.
C is not suitable as a large scale programming language. Just look at the number of defects in the Linux kernel and their attempt at extending the language through custom compiler attributes to overcome the limitations of C.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#135Earlier quoted context omitted.
This is exactly what I meant as irrelevant. If I call `foo(std::move(my_unique_ptr))`, I know for sure, statically, that my_unique_ptr was moved from, as part of the function call process, and I can no longer access it. Whether `foo` chooses to further move from it is irrelevant.
aside from what others wrote, it’s also non local - whether std::move even does anything is dependent on the signature of foo - if foo takes it by const& you may think you’ve transferred ownership when it hasn’t actually happened.
The point of contention is whether that is always the case, or whether there are situations where moving from the parameter is a runtime decision.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#136Earlier quoted context omitted.
> 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 candida…
Sure, but from the perspective of the code that has the move() its good to assume the value is moved at that call, which I guess was the intention of picking the name.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#137> Let me put this in simpler terms: std::move is like putting a sign on your object “I’m done with this, you can take its stuff.” and 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 it…
1. You must implement a move constructor or a move assignment operator in order for std::move to do anything
2. The moved object could be left in an unusable state, depending on your implementation, after stealing its internal resources.
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#138> 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!
performance-noexcept-move-constructor is great but it also complains about move assignment operators, which are completely different beasts and are practically impossible to make noexcept if your destructors throw.
match cxxConstructExpr(hasDeclaration(cxxConstructorDecl(isMoveConstructor(), unless(isNoThrow())).bind("throwing-move")))
You can put extra constraints on the caller if you'd like (e.g., isInStdNamespace()), though it's less trivial. Happy to help write something if you have a precise idea of what you want to match.Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#139I.e. if I have
``` std::string a = "hi"; std::string b = "world"; return {a, b}; // std::pair ``` I always assumed the compiler figures out that it can move these things?
If not, why not? My ide tells me I should move, surely the compiler has more context to figure that out?
Re: C++ std::move doesn't move anything: A deep dive into Value Categories
#140Should have be called give(). But naming things correctly is hard, and the C++ committee is known to do a lot of things incorrectly
The name predates the standardisation. The committee did not come with the whole thing themselves, rather they adopted and expanded already existing library implementations. You could move in C++, with this exact name, long before C++11. See, for example, this implementation https://stlab.adobe.com/group__move__related.html
Hinnant said they couldn't find a way to do destructive move and have the C++ inheritance hierarchy. To me it's obvious what loses in this case, but to a C++ programmer at the turn of the century apparently C++ implementation inheritance ("OO programming") was seen as crucial so C++ 11 move semantics are basically what's described in that proposal.