I have read several answers and and many articles about move semantic so it is simply a static cast to rvalue reference, this question is about its influence on the stack, so is the stack left fragmanted after move? or is it rearranged somehow? as the stack moved objects are not subject to stack unwinding. The following snippet runs fine:
#include <memory>
#include <cassert>
struct A {
int x = 0;
};
struct B {
A a;
};
void SetB(B& b) {
A a1{6}; //pushing into the stack.
A a2{7}; //pushing into the stack.
b.a = std::move(a2);
}
int main()
{
B b;
SetB(b);
assert( b.a.x == 7);
}
a2
is defined in SetB
stack frame but still available after SetB
is finished and the contorl back to main
. However; a1
is not despite it is closer to main
stack frame?
CodePudding user response:
There's no 'stack' in the C standard, it's an implementation detail. So a 'generic' answer is difficult as an implementation can have any kind of effect on the given architecture's stack.
That said, the std::move()
does not remove the argument from the stack, it remains in a valid-but-undefined state. For your own classes, you might even implement it. Therefore, it's not possible to 'remove' the variable from anywhere - unless, of course, in the optimization phase of the compiler, if it's not accessed anymore.
a2
is not available after SetB
is finished. The value is moved to b.a
, therefore, b.a
is expected to contain the value that a2
has contained before, but it's not the same variable (nor the same memory address).
CodePudding user response:
With this answer I want to wrap up all infos I got, which really answer my question:
- For all variables allocated in the stack
move
does normal copy (very expensive in case those variables are big) this is something I tested after answers from JaMit, user17732522 and lorro, still that is implementation detail and might get changed. Originally the question was because I though the compiler will add some measures to manage the stack without copying everything, but it looks I have over-estimatedmove
(no stack fragmentation nor rearrangement, only copy). So in the example above ifA
is defined like:
struct A {
int x[1000] = {};
};
moving A
results in copying the whole array as is.
- moving heap resources all depends on the programmer, where
move
will call move constructor, and if that constructor is the default one, it makes shallow copy of pointers which might lead to Segmentation Fault due to dangling pointers. move
is good to use when need to change the owner of somestd
objects likemap
,unique_ptr
,shared_ptr
, ... because here move constructor and assignment operator are defined well. Otherwise, one must be careful when implementing those ctor and operator.