How the hell does cpp move work
02 Mar 2025
What is the problem?
The key problem this solves is with the handling of large objects we DONT WANT TO COPY. This usually happens when we.
- Want to return our fat object
- Want to give a function our fat object
Previously to do this weâre kinda stuck and we need to either (for returning)
- Handle the memory yourself: by passing around a pointer that was created
- Modify memory that was provided: mutating a reference parameter
This is painful, if only there was a way to just return the result and have cpp just handle all this crap for us?
What is move semantics?
Basically on terminology
- lvalue: is something you can mutate, like a reference
&bean
- rvalue: something you canât mutate
&&bean
(and you can plunder đ±)
So move semantics is just the art of
- realising that something is an rvalue
- specifying a function that works with these rvalues (a move constructor and a move assignment)
simple!
If its a temporary object like a function return, or an object thats going out of scope, you can just move it freely!
How does std::move
solve our problem?
std::move
simply just tells cpp that this lvalue is actually an rvalue. Just that.
What are the best practices here and why?
Keep in mind the rule of zero
If you define any of the 5 basic special functions, you wonât get your move functions! This means that std::move
will just not do anything!
Handling fundamental types
Guess what. When you move that int, itâll call your nice move constructor or assignment, but that will simply still do a copy as its faster.
Moving const variables
Keeping that const variable a const and not mutating it sounds sane. And thats what happens.
Donât move return values.
cpp does copy ellison/RVO. This means that instead of having that return value be copied back into the calling scope, it will actually just completely removes it!
- These temporary r values are called pure r values, and are always directly constructed where they need to be!
- AKA when you initialise a returned object in a return statement
- Or when you initialise and object and construct crap in its parameters
Removing the copy itself is always better than a move. A move is still a cheaper copy:
- Copy the memory address
- Nullify the memory address of the thing youâve copied
Moving std::array
Lmao, this guy is moving std arrays, donât you know that moving that still copies all underlying elements. A std::array
is still a trivial type and therefore copied.
Appendix
https://mbevin.wordpress.com/2012/11/20/move-semantics/ https://www.nutrient.io/blog/when-cpp-doesnt-move/ https://subscription.packtpub.com/book/programming/9781839216541/2/ch02lvl1sec08/move-semantics-explained