返回值两份

时间:2016-03-24 16:28:22

标签: c++ gcc

我正按功能分析返回值。请参阅下面的实际问题:

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

我的问题是什么?

  1. 为什么有两个拷贝构造函数?我不明白为什么需要它。

2 个答案:

答案 0 :(得分:2)

调用构造函数的两次中的一次构建一个临时对象,用作f()的返回值。如果您想避免这种额外开销,则必须依赖C++11 move constructors

答案 1 :(得分:2)

调用f()内的

复制构造函数,因为使用了对象的“返回”。这会提示它创建一个临时变量的副本,然后将其传递给main。 main内部的复制构造函数显而易见f()返回S个对象,并将其复制到“s