如果没有编译器的优化,在赋值时会调用以下构造函数(下面的代码):
我知道可以始终应用返回值优化,而这取决于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的左侧。