std::move 是否会使堆栈碎片化,或者在将对象移动到调用者后堆栈是否重新排列?

mua*_*uaz 1 c++ move stack-unwinding c++11

我已经阅读了几个答案和许多有关移动语义的文章,因此它只是对右值引用的静态转换,这个问题是关于它对堆栈的影响,那么移动后堆栈是否会留下碎片?还是以某种方式重新排列?因为堆栈移动的对象不受堆栈展开的影响。以下代码片段运行良好:

#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);
}
Run Code Online (Sandbox Code Playgroud)

a2是在SetB堆栈帧中定义的,但在SetB完成并且控件返回到后仍然可用main。然而; a1不是尽管它更接近main堆栈帧吗?

lor*_*rro 6

C++ 标准中没有“堆栈”,它是一个实现细节。因此,“通用”答案很困难,因为实现可能会对给定架构的堆栈产生任何影响。

也就是说,std::move()不会从堆栈中删除参数,它仍处于有效但未定义的状态对于您自己的课程,您甚至可以实现它。因此,不可能从任何地方“删除”变量 - 当然,除非在编译器的优化阶段,如果不再访问它。

a2完成后不可使用。SetB该值被移动b.a,因此b.a预计将包含之前包含的a2,但它不是同一个变量(也不是同一个内存地址)。