Home > database >  Does std::move leave stack fragmented or is the stack rearranged after moving an object to the calle
Does std::move leave stack fragmented or is the stack rearranged after moving an object to the calle

Time:06-30

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-estimated move (no stack fragmentation nor rearrangement, only copy). So in the example above if A 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 some std objects like map, 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.
  • Related