我正按功能分析返回值。请参阅下面的实际问题:
struct S{ int a, b, c, d; };
S f(){
S s;
s.b=5;
return s;
}
int main(){
S s= f();
s.a =2;
}
来自gcc 5.3 -O0 -fno-elide-constructors
on godbolt的编译器输出:
f():
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movl $5, -28(%rbp)
leaq -32(%rbp), %rdx
leaq -16(%rbp), %rax
movq %rdx, %rsi
movq %rax, %rdi
call S::S(S const&)
movq -16(%rbp), %rax
movq -8(%rbp), %rdx
leave
ret
main:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
call f()
movq %rax, -16(%rbp)
movq %rdx, -8(%rbp)
leaq -16(%rbp), %rdx
leaq -32(%rbp), %rax
movq %rdx, %rsi
movq %rax, %rdi
call S::S(S const&)
movl $2, -32(%rbp)
movl $0, %eax
leave
ret
我的问题是什么?
答案 0 :(得分:2)
调用构造函数的两次中的一次构建一个临时对象,用作f()
的返回值。如果您想避免这种额外开销,则必须依赖C++11 move constructors。
答案 1 :(得分:2)
f()
内的复制构造函数,因为使用了对象的“返回”。这会提示它创建一个临时变量的副本,然后将其传递给main
。 main内部的复制构造函数显而易见f()
返回S
个对象,并将其复制到“s
”