在调用者堆栈框架上是否需要临时对象?

时间:2018-03-01 16:27:10

标签: c++

如果没有编译器的优化,在赋值时会调用以下构造函数(下面的代码):

  • 构造函数(内部函数)
  • 移动构造函数(移动到调用者堆栈上的保留位置?)
  • 移动构造函数(调用者从保留位置移动到调用者堆栈上的目标位置)

我知道可以始终应用返回值优化,而这取决于NRVO的程序流程。但是,在这两种情况下似乎都应用了一个优化(无需第一次移动并直接移动到目的地)。

示例:

struct Data { 
  char bytes[1600]; 
};

Data f() {
  Data result = {};
  return result;
}

int main() {
  Data d = f();
}

没有优化(-fno-elide-constructors)[占用调用者堆栈帧空间的2倍]:

main:
  push rbp
  mov rbp, rsp
  sub rsp, 3200

f():
  push rbp
  mov rbp, rsp
  sub rsp, 1616

有了elide:

main:
  push rbp
  mov rbp, rsp
  sub rsp, 1600

我的问题是:是否有任何情况需要进行2次移动/隐藏"调用者堆栈上的temperory对象?如果可以应用NRVO或RVO,则没有移动,如果不可能有1次优化移动(直接到左侧操作员的位置)。

看起来调用者堆栈上隐藏的临时对象只是浪费空间并且总是可以防止额外的移动,因为调用者已经知道应该将结果移动到哪里。它总是可以在函数中构造相应的数据,并将其复制/移动到赋值左侧的位置。不需要构造= copy => hidden object = copy> assigment的左侧。

0 个答案:

没有答案