首页 > 代码库 > 一个函数返回临时对象引起的编译器优化问题

一个函数返回临时对象引起的编译器优化问题

我们都知道,如果在一个函数调用另一个函数,假设是 main 函数调用 fun 函数,这个 fun 函数返回一个临时类类型变量,那么这个时候编译器就会在 main 函数申请一个空间并生成一个临时对象,通过拷贝构造函数将 fun 返回的临时变量的值拷贝到这个临时对象。我们看如下的代码:

#include <iostream> #include <cstring>  using namespace std;   class Matrix  {  public:          explicit Matrix(double d = 1.0)          {              cout << "Matrix::Matrix()" << endl;               for(int i = 0; i < 10; i++)                  for(int j = 0; j < 10; j++)                      m[i][j] = d;          }           Matrix(const Matrix& mt)          {              cout << "Matrix::Matrix(const Matrix&)" << endl;              memcpy(this, &mt, sizeof(Matrix));          }           Matrix& operator=(const Matrix& mt)          {              if(this == &mt)                  return *this;               cout << "Matrix::operator=(const Matrix&)" << endl;              memcpy(this, &mt, sizeof(Matrix));               return *this;          }           friend const Matrix operator+(const Matrix&, const Matrix&);          //...   private:          double m[10][10];  };   const Matrix operator+(const Matrix& arg1, const Matrix& arg2)  {          Matrix sum;          for(int i = 0; i < 10; i++)              for(int j = 0; j < 10; j++)                  sum.m[i][j] = arg1.m[i][j] + arg2.m[i][j];  return sum; }   int main()  {          Matrix a(2.0),  b(3.0);        Matrix c = (a + b);  return 0;  } 

按照我们的预期,输出结果应该是这样的:

这也正是 vs2012 的执行结果,但是在 GCC4.2.1 中的执行结果却是这样的:

这样看来,在构造 c 的时候根本就没有调用拷贝构造函数,同时也没用调用赋值操作符和构造函数。这样就会有一个问题,c 到底是怎么构造的?我们把代码改成这样:

#include <iostream> #include <cstring>  using namespace std;   class Matrix  {  public:          explicit Matrix(double d = 1.0)          {              cout << "Matrix::Matrix()" << endl;               for(int i = 0; i < 10; i++)                  for(int j = 0; j < 10; j++)                      m[i][j] = d;          }           Matrix(const Matrix& mt)          {              cout << "Matrix::Matrix(const Matrix&)" << endl;              memcpy(this, &mt, sizeof(Matrix));          }           Matrix& operator=(const Matrix& mt)          {              if(this == &mt)                  return *this;               cout << "Matrix::operator=(const Matrix&)" << endl;              memcpy(this, &mt, sizeof(Matrix));               return *this;          }           friend const Matrix operator+(const Matrix&, const Matrix&);          //...   private:          double m[10][10];  };   const Matrix operator+(const Matrix& arg1, const Matrix& arg2)  {          Matrix sum;          for(int i = 0; i < 10; i++)              for(int j = 0; j < 10; j++)                  sum.m[i][j] = arg1.m[i][j] + arg2.m[i][j];          cout << "Address of sum: " << &sum << endl;        return sum; }   int main()  {          Matrix a(2.0),  b(3.0);        Matrix c = (a + b);          cout << "Address of c:   " << &c << endl;         return 0;  } 

其实就是把 sum 和 c 的地址打了出来,我们会发现在 gcc 的结果如下:

从这里可以看出,gcc 编译器对 c 的初始化做了优化,它没有再调用拷贝构造函数来构造 c,而是直接让 c 指向了 + 函数里的临时变量。当然这里也让 sum 的空间所有权交给了 main 作用域的 c, 否则在推出 sum 的时候 sum 的空间就应该被释放了。

这只是我从其执行结果推测的结果,而 gcc 产生的目标文件的汇编代码简直没法看,所以没有研究其汇编代码来验证我的想法,有人看得懂 gcc 的汇编代码的看完结果望告知!下面是代码的gcc汇编代码:

    .section    __TEXT,__text,regular,pure_instructions    .globl    __ZplRK6MatrixS1_    .align    4, 0x90__ZplRK6MatrixS1_:                      ## @_ZplRK6MatrixS1_    .cfi_startproc## BB#0:    pushq    %rbpLtmp2:    .cfi_def_cfa_offset 16Ltmp3:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp4:    .cfi_def_cfa_register %rbp    subq    $64, %rsp    movq    %rdi, %rax    movabsq    $1, %rcx    cvtsi2sdq    %rcx, %xmm0    movq    %rsi, -24(%rbp)    movq    %rdx, -32(%rbp)    movq    %rdi, -48(%rbp)         ## 8-byte Spill    movq    %rax, -56(%rbp)         ## 8-byte Spill    callq    __ZN6MatrixC1Ed    movl    $0, -36(%rbp)LBB0_1:                                 ## =>This Loop Header: Depth=1                                        ##     Child Loop BB0_3 Depth 2    cmpl    $10, -36(%rbp)    jge    LBB0_8## BB#2:                                ##   in Loop: Header=BB0_1 Depth=1    movl    $0, -40(%rbp)LBB0_3:                                 ##   Parent Loop BB0_1 Depth=1                                        ## =>  This Inner Loop Header: Depth=2    cmpl    $10, -40(%rbp)    jge    LBB0_6## BB#4:                                ##   in Loop: Header=BB0_3 Depth=2    movslq    -40(%rbp), %rax    movslq    -36(%rbp), %rcx    movq    -24(%rbp), %rdx    imulq    $80, %rcx, %rcx    addq    %rcx, %rdx    movsd    (%rdx,%rax,8), %xmm0    movslq    -40(%rbp), %rax    movslq    -36(%rbp), %rcx    movq    -32(%rbp), %rdx    imulq    $80, %rcx, %rcx    addq    %rcx, %rdx    addsd    (%rdx,%rax,8), %xmm0    movslq    -40(%rbp), %rax    movslq    -36(%rbp), %rcx    imulq    $80, %rcx, %rcx    movq    -48(%rbp), %rdx         ## 8-byte Reload    addq    %rcx, %rdx    movsd    %xmm0, (%rdx,%rax,8)## BB#5:                                ##   in Loop: Header=BB0_3 Depth=2    movl    -40(%rbp), %eax    addl    $1, %eax    movl    %eax, -40(%rbp)    jmp    LBB0_3LBB0_6:                                 ##   in Loop: Header=BB0_1 Depth=1    jmp    LBB0_7LBB0_7:                                 ##   in Loop: Header=BB0_1 Depth=1    movl    -36(%rbp), %eax    addl    $1, %eax    movl    %eax, -36(%rbp)    jmp    LBB0_1LBB0_8:    movq    __ZNSt3__14coutE@GOTPCREL(%rip), %rdi    leaq    L_.str(%rip), %rsi    callq    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc    movq    -48(%rbp), %rsi         ## 8-byte Reload    movq    %rax, %rdi    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPKv    leaq    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_(%rip), %rsi    movq    %rax, -8(%rbp)    movq    %rsi, -16(%rbp)    movq    -8(%rbp), %rdi    callq    *-16(%rbp)    movq    -56(%rbp), %rsi         ## 8-byte Reload    movq    %rax, -64(%rbp)         ## 8-byte Spill    movq    %rsi, %rax    addq    $64, %rsp    popq    %rbp    retq    .cfi_endproc    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions    .globl    __ZN6MatrixC1Ed    .weak_def_can_be_hidden    __ZN6MatrixC1Ed    .align    4, 0x90__ZN6MatrixC1Ed:                        ## @_ZN6MatrixC1Ed    .cfi_startproc## BB#0:    pushq    %rbpLtmp7:    .cfi_def_cfa_offset 16Ltmp8:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp9:    .cfi_def_cfa_register %rbp    subq    $16, %rsp    movq    %rdi, -8(%rbp)    movsd    %xmm0, -16(%rbp)    movq    -8(%rbp), %rdi    movsd    -16(%rbp), %xmm0    callq    __ZN6MatrixC2Ed    addq    $16, %rsp    popq    %rbp    retq    .cfi_endproc    .globl    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc    .weak_def_can_be_hidden    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc    .align    4, 0x90__ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc: ## @_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc    .cfi_startproc## BB#0:    pushq    %rbpLtmp12:    .cfi_def_cfa_offset 16Ltmp13:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp14:    .cfi_def_cfa_register %rbp    subq    $48, %rsp    movq    %rdi, -16(%rbp)    movq    %rsi, -24(%rbp)    movq    -16(%rbp), %rdi    movq    -24(%rbp), %rsi    movq    -24(%rbp), %rax    movq    %rax, -8(%rbp)    movq    -8(%rbp), %rax    movq    %rdi, -32(%rbp)         ## 8-byte Spill    movq    %rax, %rdi    movq    %rsi, -40(%rbp)         ## 8-byte Spill    callq    _strlen    movq    -32(%rbp), %rdi         ## 8-byte Reload    movq    -40(%rbp), %rsi         ## 8-byte Reload    movq    %rax, %rdx    callq    __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m    addq    $48, %rsp    popq    %rbp    retq    .cfi_endproc    .private_extern    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_    .globl    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_    .weak_definition    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_    .align    4, 0x90__ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_: ## @_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_    .cfi_startproc    .cfi_personality 155, ___gxx_personality_v0Leh_func_begin3:    .cfi_lsda 16, Lexception3## BB#0:    pushq    %rbpLtmp25:    .cfi_def_cfa_offset 16Ltmp26:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp27:    .cfi_def_cfa_register %rbp    subq    $144, %rsp    movq    %rdi, -72(%rbp)    movq    %rdi, %rax    movq    (%rdi), %rcx    movq    -24(%rcx), %rcx    addq    %rcx, %rdi    movq    %rdi, -32(%rbp)    movb    $10, -33(%rbp)    movq    -32(%rbp), %rsi    leaq    -48(%rbp), %rcx    movq    %rcx, %rdi    movq    %rax, -80(%rbp)         ## 8-byte Spill    movq    %rcx, -88(%rbp)         ## 8-byte Spill    callq    __ZNKSt3__18ios_base6getlocEv    movq    -88(%rbp), %rax         ## 8-byte Reload    movq    %rax, -24(%rbp)Ltmp15:    movq    __ZNSt3__15ctypeIcE2idE@GOTPCREL(%rip), %rsi    movq    %rax, %rdi    callq    __ZNKSt3__16locale9use_facetERNS0_2idELtmp16:    movq    %rax, -96(%rbp)         ## 8-byte Spill    jmp    LBB3_1LBB3_1:                                 ## %_ZNSt3__19use_facetINS_5ctypeIcEEEERKT_RKNS_6localeE.exit.i    movb    -33(%rbp), %al    movq    -96(%rbp), %rcx         ## 8-byte Reload    movq    %rcx, -8(%rbp)    movb    %al, -9(%rbp)    movq    -8(%rbp), %rdx    movq    (%rdx), %rsi    movq    56(%rsi), %rsi    movsbl    -9(%rbp), %ediLtmp17:    movl    %edi, -100(%rbp)        ## 4-byte Spill    movq    %rdx, %rdi    movl    -100(%rbp), %r8d        ## 4-byte Reload    movq    %rsi, -112(%rbp)        ## 8-byte Spill    movl    %r8d, %esi    movq    -112(%rbp), %rdx        ## 8-byte Reload    callq    *%rdxLtmp18:    movb    %al, -113(%rbp)         ## 1-byte Spill    jmp    LBB3_5LBB3_2:Ltmp19:    movl    %edx, %ecx    movq    %rax, -56(%rbp)    movl    %ecx, -60(%rbp)Ltmp20:    leaq    -48(%rbp), %rdi    callq    __ZNSt3__16localeD1EvLtmp21:    jmp    LBB3_3LBB3_3:    movq    -56(%rbp), %rdi    callq    __Unwind_ResumeLBB3_4:Ltmp22:    movl    %edx, %ecx    movq    %rax, %rdi    movl    %ecx, -120(%rbp)        ## 4-byte Spill    callq    ___clang_call_terminateLBB3_5:                                 ## %_ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenEc.exit    leaq    -48(%rbp), %rdi    callq    __ZNSt3__16localeD1Ev    movq    -80(%rbp), %rdi         ## 8-byte Reload    movb    -113(%rbp), %al         ## 1-byte Reload    movsbl    %al, %esi    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE3putEc    movq    -72(%rbp), %rdi    movq    %rax, -128(%rbp)        ## 8-byte Spill    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5flushEv    movq    -72(%rbp), %rdi    movq    %rax, -136(%rbp)        ## 8-byte Spill    movq    %rdi, %rax    addq    $144, %rsp    popq    %rbp    retq    .cfi_endprocLeh_func_end3:    .section    __TEXT,__gcc_except_tab    .align    2GCC_except_table3:Lexception3:    .byte    255                     ## @LPStart Encoding = omit    .byte    155                     ## @TType Encoding = indirect pcrel sdata4    .asciz    "\274"                  ## @TType base offset    .byte    3                       ## Call site Encoding = udata4    .byte    52                      ## Call site table lengthLset0 = Leh_func_begin3-Leh_func_begin3 ## >> Call Site 1 <<    .long    Lset0Lset1 = Ltmp15-Leh_func_begin3          ##   Call between Leh_func_begin3 and Ltmp15    .long    Lset1    .long    0                       ##     has no landing pad    .byte    0                       ##   On action: cleanupLset2 = Ltmp15-Leh_func_begin3          ## >> Call Site 2 <<    .long    Lset2Lset3 = Ltmp18-Ltmp15                   ##   Call between Ltmp15 and Ltmp18    .long    Lset3Lset4 = Ltmp19-Leh_func_begin3          ##     jumps to Ltmp19    .long    Lset4    .byte    0                       ##   On action: cleanupLset5 = Ltmp20-Leh_func_begin3          ## >> Call Site 3 <<    .long    Lset5Lset6 = Ltmp21-Ltmp20                   ##   Call between Ltmp20 and Ltmp21    .long    Lset6Lset7 = Ltmp22-Leh_func_begin3          ##     jumps to Ltmp22    .long    Lset7    .byte    1                       ##   On action: 1Lset8 = Ltmp21-Leh_func_begin3          ## >> Call Site 4 <<    .long    Lset8Lset9 = Leh_func_end3-Ltmp21            ##   Call between Ltmp21 and Leh_func_end3    .long    Lset9    .long    0                       ##     has no landing pad    .byte    0                       ##   On action: cleanup    .byte    1                       ## >> Action Record 1 <<                                        ##   Catch TypeInfo 1    .byte    0                       ##   No further actions                                        ## >> Catch TypeInfos <<    .long    0                       ## TypeInfo 1    .align    2    .section    __TEXT,__text,regular,pure_instructions    .globl    _main    .align    4, 0x90_main:                                  ## @main    .cfi_startproc## BB#0:    pushq    %rbpLtmp30:    .cfi_def_cfa_offset 16Ltmp31:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp32:    .cfi_def_cfa_register %rbp    subq    $2448, %rsp             ## imm = 0x990    leaq    -824(%rbp), %rdi    movabsq    $2, %rax    cvtsi2sdq    %rax, %xmm0    movl    $0, -20(%rbp)    callq    __ZN6MatrixC1Ed    leaq    -1624(%rbp), %rdi    movabsq    $3, %rax    cvtsi2sdq    %rax, %xmm0    callq    __ZN6MatrixC1Ed    leaq    -2424(%rbp), %rdi    leaq    -824(%rbp), %rsi    leaq    -1624(%rbp), %rdx    callq    __ZplRK6MatrixS1_    movq    __ZNSt3__14coutE@GOTPCREL(%rip), %rdi    leaq    L_.str1(%rip), %rsi    callq    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc    leaq    -2424(%rbp), %rdx    movq    %rax, %rdi    movq    %rdx, %rsi    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPKv    movl    $0, %ecx    leaq    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_(%rip), %rdx    movq    %rax, -8(%rbp)    movq    %rdx, -16(%rbp)    movq    -8(%rbp), %rdi    movl    %ecx, -2428(%rbp)       ## 4-byte Spill    callq    *-16(%rbp)    movl    -2428(%rbp), %ecx       ## 4-byte Reload    movq    %rax, -2440(%rbp)       ## 8-byte Spill    movl    %ecx, %eax    addq    $2448, %rsp             ## imm = 0x990    popq    %rbp    retq    .cfi_endproc    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions    .private_extern    ___clang_call_terminate    .globl    ___clang_call_terminate    .weak_def_can_be_hidden    ___clang_call_terminate    .align    4, 0x90___clang_call_terminate:                ## @__clang_call_terminate## BB#0:    pushq    %rbp    movq    %rsp, %rbp    subq    $16, %rsp    callq    ___cxa_begin_catch    movq    %rax, -8(%rbp)          ## 8-byte Spill    callq    __ZSt9terminatev    .globl    __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m    .weak_def_can_be_hidden    __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m    .align    4, 0x90__ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m: ## @_ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m    .cfi_startproc    .cfi_personality 155, ___gxx_personality_v0Leh_func_begin6:    .cfi_lsda 16, Lexception6## BB#0:    pushq    %rbpLtmp65:    .cfi_def_cfa_offset 16Ltmp66:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp67:    .cfi_def_cfa_register %rbp    subq    $416, %rsp              ## imm = 0x1A0    movq    %rdi, -208(%rbp)    movq    %rsi, -216(%rbp)    movq    %rdx, -224(%rbp)    movq    -208(%rbp), %rsiLtmp33:    leaq    -240(%rbp), %rdi    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryC1ERS3_Ltmp34:    jmp    LBB6_1LBB6_1:    leaq    -240(%rbp), %rax    movq    %rax, -200(%rbp)    movq    -200(%rbp), %rax    movb    (%rax), %cl    movb    %cl, -273(%rbp)         ## 1-byte Spill## BB#2:    movb    -273(%rbp), %al         ## 1-byte Reload    testb    $1, %al    jne    LBB6_3    jmp    LBB6_26LBB6_3:    leaq    -264(%rbp), %rax    movq    -208(%rbp), %rcx    movq    %rax, -184(%rbp)    movq    %rcx, -192(%rbp)    movq    -184(%rbp), %rax    movq    -192(%rbp), %rcx    movq    %rax, -152(%rbp)    movq    %rcx, -160(%rbp)    movq    -152(%rbp), %rax    movq    -160(%rbp), %rcx    movq    (%rcx), %rdx    movq    -24(%rdx), %rdx    addq    %rdx, %rcx    movq    %rcx, -144(%rbp)    movq    -144(%rbp), %rcx    movq    %rcx, -136(%rbp)    movq    -136(%rbp), %rcx    movq    40(%rcx), %rcx    movq    %rcx, (%rax)    movq    -216(%rbp), %rsi    movq    -208(%rbp), %rax    movq    (%rax), %rcx    movq    -24(%rcx), %rcx    addq    %rcx, %rax    movq    %rax, -96(%rbp)    movq    -96(%rbp), %rax    movl    8(%rax), %edi    movq    %rsi, -288(%rbp)        ## 8-byte Spill    movl    %edi, -292(%rbp)        ## 4-byte Spill## BB#4:    movl    -292(%rbp), %eax        ## 4-byte Reload    andl    $176, %eax    cmpl    $32, %eax    jne    LBB6_6## BB#5:    movq    -216(%rbp), %rax    addq    -224(%rbp), %rax    movq    %rax, -304(%rbp)        ## 8-byte Spill    jmp    LBB6_7LBB6_6:    movq    -216(%rbp), %rax    movq    %rax, -304(%rbp)        ## 8-byte SpillLBB6_7:    movq    -304(%rbp), %rax        ## 8-byte Reload    movq    -216(%rbp), %rcx    addq    -224(%rbp), %rcx    movq    -208(%rbp), %rdx    movq    (%rdx), %rsi    movq    -24(%rsi), %rsi    addq    %rsi, %rdx    movq    -208(%rbp), %rsi    movq    (%rsi), %rdi    movq    -24(%rdi), %rdi    addq    %rdi, %rsi    movq    %rsi, -80(%rbp)    movq    -80(%rbp), %rsi    movl    144(%rsi), %r8d    movl    $-1, -4(%rbp)    movl    %r8d, -8(%rbp)    movl    -4(%rbp), %r8d    cmpl    -8(%rbp), %r8d    movq    %rax, -312(%rbp)        ## 8-byte Spill    movq    %rcx, -320(%rbp)        ## 8-byte Spill    movq    %rdx, -328(%rbp)        ## 8-byte Spill    movq    %rsi, -336(%rbp)        ## 8-byte Spill    jne    LBB6_16## BB#8:    movq    -336(%rbp), %rax        ## 8-byte Reload    movq    %rax, -40(%rbp)    movb    $32, -41(%rbp)    movq    -40(%rbp), %rsiLtmp35:    leaq    -56(%rbp), %rdi    callq    __ZNKSt3__18ios_base6getlocEvLtmp36:    jmp    LBB6_9LBB6_9:                                 ## %.noexc    leaq    -56(%rbp), %rax    movq    %rax, -32(%rbp)Ltmp37:    movq    __ZNSt3__15ctypeIcE2idE@GOTPCREL(%rip), %rsi    movq    %rax, %rdi    callq    __ZNKSt3__16locale9use_facetERNS0_2idELtmp38:    movq    %rax, -344(%rbp)        ## 8-byte Spill    jmp    LBB6_10LBB6_10:                                ## %_ZNSt3__19use_facetINS_5ctypeIcEEEERKT_RKNS_6localeE.exit.i.i    movb    -41(%rbp), %al    movq    -344(%rbp), %rcx        ## 8-byte Reload    movq    %rcx, -16(%rbp)    movb    %al, -17(%rbp)    movq    -16(%rbp), %rdx    movq    (%rdx), %rsi    movq    56(%rsi), %rsi    movsbl    -17(%rbp), %ediLtmp39:    movl    %edi, -348(%rbp)        ## 4-byte Spill    movq    %rdx, %rdi    movl    -348(%rbp), %r8d        ## 4-byte Reload    movq    %rsi, -360(%rbp)        ## 8-byte Spill    movl    %r8d, %esi    movq    -360(%rbp), %rdx        ## 8-byte Reload    callq    *%rdxLtmp40:    movb    %al, -361(%rbp)         ## 1-byte Spill    jmp    LBB6_14LBB6_11:Ltmp41:    movl    %edx, %ecx    movq    %rax, -64(%rbp)    movl    %ecx, -68(%rbp)Ltmp42:    leaq    -56(%rbp), %rdi    callq    __ZNSt3__16localeD1EvLtmp43:    jmp    LBB6_12LBB6_12:    movq    -64(%rbp), %rax    movl    -68(%rbp), %ecx    movq    %rax, -376(%rbp)        ## 8-byte Spill    movl    %ecx, -380(%rbp)        ## 4-byte Spill    jmp    LBB6_24LBB6_13:Ltmp44:    movl    %edx, %ecx    movq    %rax, %rdi    movl    %ecx, -384(%rbp)        ## 4-byte Spill    callq    ___clang_call_terminateLBB6_14:                                ## %_ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenEc.exit.iLtmp45:    leaq    -56(%rbp), %rdi    callq    __ZNSt3__16localeD1EvLtmp46:    jmp    LBB6_15LBB6_15:                                ## %.noexc1    movb    -361(%rbp), %al         ## 1-byte Reload    movsbl    %al, %ecx    movq    -336(%rbp), %rdx        ## 8-byte Reload    movl    %ecx, 144(%rdx)LBB6_16:                                ## %_ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE4fillEv.exit    movq    -336(%rbp), %rax        ## 8-byte Reload    movl    144(%rax), %ecx    movb    %cl, %dl    movb    %dl, -385(%rbp)         ## 1-byte Spill## BB#17:    movq    -264(%rbp), %rdiLtmp47:    movb    -385(%rbp), %al         ## 1-byte Reload    movsbl    %al, %r9d    movq    -288(%rbp), %rsi        ## 8-byte Reload    movq    -312(%rbp), %rdx        ## 8-byte Reload    movq    -320(%rbp), %rcx        ## 8-byte Reload    movq    -328(%rbp), %r8         ## 8-byte Reload    callq    __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_Ltmp48:    movq    %rax, -400(%rbp)        ## 8-byte Spill    jmp    LBB6_18LBB6_18:    leaq    -272(%rbp), %rax    movq    -400(%rbp), %rcx        ## 8-byte Reload    movq    %rcx, -272(%rbp)    movq    %rax, -88(%rbp)    movq    -88(%rbp), %rax    cmpq    $0, (%rax)    jne    LBB6_25## BB#19:    movq    -208(%rbp), %rax    movq    (%rax), %rcx    movq    -24(%rcx), %rcx    addq    %rcx, %rax    movq    %rax, -120(%rbp)    movl    $5, -124(%rbp)    movq    -120(%rbp), %rax    movq    %rax, -104(%rbp)    movl    $5, -108(%rbp)    movq    -104(%rbp), %rax    movl    32(%rax), %edx    orl    $5, %edxLtmp49:    movq    %rax, %rdi    movl    %edx, %esi    callq    __ZNSt3__18ios_base5clearEjLtmp50:    jmp    LBB6_20LBB6_20:                                ## %_ZNSt3__19basic_iosIcNS_11char_traitsIcEEE8setstateEj.exit    jmp    LBB6_21LBB6_21:    jmp    LBB6_25LBB6_22:Ltmp56:    movl    %edx, %ecx    movq    %rax, -248(%rbp)    movl    %ecx, -252(%rbp)    jmp    LBB6_29LBB6_23:Ltmp51:    movl    %edx, %ecx    movq    %rax, -376(%rbp)        ## 8-byte Spill    movl    %ecx, -380(%rbp)        ## 4-byte SpillLBB6_24:                                ## %.body    movl    -380(%rbp), %eax        ## 4-byte Reload    movq    -376(%rbp), %rcx        ## 8-byte Reload    movq    %rcx, -248(%rbp)    movl    %eax, -252(%rbp)Ltmp52:    leaq    -240(%rbp), %rdi    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1EvLtmp53:    jmp    LBB6_28LBB6_25:    jmp    LBB6_26LBB6_26:Ltmp54:    leaq    -240(%rbp), %rdi    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1EvLtmp55:    jmp    LBB6_27LBB6_27:    jmp    LBB6_31LBB6_28:    jmp    LBB6_29LBB6_29:    movq    -248(%rbp), %rdi    callq    ___cxa_begin_catch    movq    -208(%rbp), %rdi    movq    (%rdi), %rcx    movq    -24(%rcx), %rcx    addq    %rcx, %rdiLtmp57:    movq    %rax, -408(%rbp)        ## 8-byte Spill    callq    __ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEvLtmp58:    jmp    LBB6_30LBB6_30:    callq    ___cxa_end_catchLBB6_31:    movq    -208(%rbp), %rax    addq    $416, %rsp              ## imm = 0x1A0    popq    %rbp    retqLBB6_32:Ltmp59:    movl    %edx, %ecx    movq    %rax, -248(%rbp)    movl    %ecx, -252(%rbp)Ltmp60:    callq    ___cxa_end_catchLtmp61:    jmp    LBB6_33LBB6_33:    jmp    LBB6_34LBB6_34:    movq    -248(%rbp), %rdi    callq    __Unwind_ResumeLBB6_35:Ltmp62:    movl    %edx, %ecx    movq    %rax, %rdi    movl    %ecx, -412(%rbp)        ## 4-byte Spill    callq    ___clang_call_terminate    .cfi_endprocLeh_func_end6:    .section    __TEXT,__gcc_except_tab    .align    2GCC_except_table6:Lexception6:    .byte    255                     ## @LPStart Encoding = omit    .byte    155                     ## @TType Encoding = indirect pcrel sdata4    .asciz    "\253\201"              ## @TType base offset    .byte    3                       ## Call site Encoding = udata4    .ascii    "\234\001"              ## Call site table lengthLset10 = Ltmp33-Leh_func_begin6         ## >> Call Site 1 <<    .long    Lset10Lset11 = Ltmp34-Ltmp33                  ##   Call between Ltmp33 and Ltmp34    .long    Lset11Lset12 = Ltmp56-Leh_func_begin6         ##     jumps to Ltmp56    .long    Lset12    .byte    5                       ##   On action: 3Lset13 = Ltmp35-Leh_func_begin6         ## >> Call Site 2 <<    .long    Lset13Lset14 = Ltmp36-Ltmp35                  ##   Call between Ltmp35 and Ltmp36    .long    Lset14Lset15 = Ltmp51-Leh_func_begin6         ##     jumps to Ltmp51    .long    Lset15    .byte    5                       ##   On action: 3Lset16 = Ltmp37-Leh_func_begin6         ## >> Call Site 3 <<    .long    Lset16Lset17 = Ltmp40-Ltmp37                  ##   Call between Ltmp37 and Ltmp40    .long    Lset17Lset18 = Ltmp41-Leh_func_begin6         ##     jumps to Ltmp41    .long    Lset18    .byte    3                       ##   On action: 2Lset19 = Ltmp42-Leh_func_begin6         ## >> Call Site 4 <<    .long    Lset19Lset20 = Ltmp43-Ltmp42                  ##   Call between Ltmp42 and Ltmp43    .long    Lset20Lset21 = Ltmp44-Leh_func_begin6         ##     jumps to Ltmp44    .long    Lset21    .byte    7                       ##   On action: 4Lset22 = Ltmp45-Leh_func_begin6         ## >> Call Site 5 <<    .long    Lset22Lset23 = Ltmp50-Ltmp45                  ##   Call between Ltmp45 and Ltmp50    .long    Lset23Lset24 = Ltmp51-Leh_func_begin6         ##     jumps to Ltmp51    .long    Lset24    .byte    5                       ##   On action: 3Lset25 = Ltmp52-Leh_func_begin6         ## >> Call Site 6 <<    .long    Lset25Lset26 = Ltmp53-Ltmp52                  ##   Call between Ltmp52 and Ltmp53    .long    Lset26Lset27 = Ltmp62-Leh_func_begin6         ##     jumps to Ltmp62    .long    Lset27    .byte    5                       ##   On action: 3Lset28 = Ltmp54-Leh_func_begin6         ## >> Call Site 7 <<    .long    Lset28Lset29 = Ltmp55-Ltmp54                  ##   Call between Ltmp54 and Ltmp55    .long    Lset29Lset30 = Ltmp56-Leh_func_begin6         ##     jumps to Ltmp56    .long    Lset30    .byte    5                       ##   On action: 3Lset31 = Ltmp55-Leh_func_begin6         ## >> Call Site 8 <<    .long    Lset31Lset32 = Ltmp57-Ltmp55                  ##   Call between Ltmp55 and Ltmp57    .long    Lset32    .long    0                       ##     has no landing pad    .byte    0                       ##   On action: cleanupLset33 = Ltmp57-Leh_func_begin6         ## >> Call Site 9 <<    .long    Lset33Lset34 = Ltmp58-Ltmp57                  ##   Call between Ltmp57 and Ltmp58    .long    Lset34Lset35 = Ltmp59-Leh_func_begin6         ##     jumps to Ltmp59    .long    Lset35    .byte    0                       ##   On action: cleanupLset36 = Ltmp58-Leh_func_begin6         ## >> Call Site 10 <<    .long    Lset36Lset37 = Ltmp60-Ltmp58                  ##   Call between Ltmp58 and Ltmp60    .long    Lset37    .long    0                       ##     has no landing pad    .byte    0                       ##   On action: cleanupLset38 = Ltmp60-Leh_func_begin6         ## >> Call Site 11 <<    .long    Lset38Lset39 = Ltmp61-Ltmp60                  ##   Call between Ltmp60 and Ltmp61    .long    Lset39Lset40 = Ltmp62-Leh_func_begin6         ##     jumps to Ltmp62    .long    Lset40    .byte    5                       ##   On action: 3Lset41 = Ltmp61-Leh_func_begin6         ## >> Call Site 12 <<    .long    Lset41Lset42 = Leh_func_end6-Ltmp61           ##   Call between Ltmp61 and Leh_func_end6    .long    Lset42    .long    0                       ##     has no landing pad    .byte    0                       ##   On action: cleanup    .byte    0                       ## >> Action Record 1 <<                                        ##   Cleanup    .byte    0                       ##   No further actions    .byte    1                       ## >> Action Record 2 <<                                        ##   Catch TypeInfo 1    .byte    125                     ##   Continue to action 1    .byte    1                       ## >> Action Record 3 <<                                        ##   Catch TypeInfo 1    .byte    0                       ##   No further actions    .byte    1                       ## >> Action Record 4 <<                                        ##   Catch TypeInfo 1    .byte    125                     ##   Continue to action 3                                        ## >> Catch TypeInfos <<    .long    0                       ## TypeInfo 1    .align    2    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions    .private_extern    __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_    .globl    __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_    .weak_def_can_be_hidden    __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_    .align    4, 0x90__ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_: ## @_ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_    .cfi_startproc    .cfi_personality 155, ___gxx_personality_v0Leh_func_begin7:    .cfi_lsda 16, Lexception7## BB#0:    pushq    %rbpLtmp76:    .cfi_def_cfa_offset 16Ltmp77:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp78:    .cfi_def_cfa_register %rbp    subq    $720, %rsp              ## imm = 0x2D0    movb    %r9b, %al    leaq    -552(%rbp), %r10    leaq    -488(%rbp), %r11    movq    %rdi, -504(%rbp)    movq    %rsi, -512(%rbp)    movq    %rdx, -520(%rbp)    movq    %rcx, -528(%rbp)    movq    %r8, -536(%rbp)    movb    %al, -537(%rbp)    movq    -504(%rbp), %rcx    movq    %r11, -472(%rbp)    movq    $-1, -480(%rbp)    movq    -472(%rbp), %rdx    movq    -480(%rbp), %rsi    movq    %rdx, -456(%rbp)    movq    %rsi, -464(%rbp)    movq    -456(%rbp), %rdx    movq    $0, (%rdx)    movq    -488(%rbp), %rdx    movq    %rdx, -552(%rbp)    movq    %r10, -448(%rbp)    cmpq    $0, %rcx    jne    LBB7_2## BB#1:    movq    -504(%rbp), %rax    movq    %rax, -496(%rbp)    jmp    LBB7_29LBB7_2:    movq    -528(%rbp), %rax    movq    -512(%rbp), %rcx    subq    %rcx, %rax    movq    %rax, -560(%rbp)    movq    -536(%rbp), %rax    movq    %rax, -344(%rbp)    movq    -344(%rbp), %rax    movq    24(%rax), %rax    movq    %rax, -568(%rbp)    movq    -568(%rbp), %rax    cmpq    -560(%rbp), %rax    jle    LBB7_4## BB#3:    movq    -560(%rbp), %rax    movq    -568(%rbp), %rcx    subq    %rax, %rcx    movq    %rcx, -568(%rbp)    jmp    LBB7_5LBB7_4:    movq    $0, -568(%rbp)LBB7_5:    movq    -520(%rbp), %rax    movq    -512(%rbp), %rcx    subq    %rcx, %rax    movq    %rax, -576(%rbp)    cmpq    $0, -576(%rbp)    jle    LBB7_9## BB#6:    movq    -504(%rbp), %rax    movq    -512(%rbp), %rcx    movq    -576(%rbp), %rdx    movq    %rax, -248(%rbp)    movq    %rcx, -256(%rbp)    movq    %rdx, -264(%rbp)    movq    -248(%rbp), %rax    movq    (%rax), %rcx    movq    96(%rcx), %rcx    movq    -256(%rbp), %rsi    movq    -264(%rbp), %rdx    movq    %rax, %rdi    callq    *%rcx    cmpq    -576(%rbp), %rax    je    LBB7_8## BB#7:    leaq    -584(%rbp), %rax    leaq    -240(%rbp), %rcx    movq    %rcx, -224(%rbp)    movq    $-1, -232(%rbp)    movq    -224(%rbp), %rcx    movq    -232(%rbp), %rdx    movq    %rcx, -208(%rbp)    movq    %rdx, -216(%rbp)    movq    -208(%rbp), %rcx    movq    $0, (%rcx)    movq    -240(%rbp), %rcx    movq    %rcx, -584(%rbp)    movq    %rax, -8(%rbp)    movq    $0, -504(%rbp)    movq    -504(%rbp), %rax    movq    %rax, -496(%rbp)    jmp    LBB7_29LBB7_8:    jmp    LBB7_9LBB7_9:    cmpq    $0, -568(%rbp)    jle    LBB7_24## BB#10:    leaq    -608(%rbp), %rax    movq    -568(%rbp), %rcx    movb    -537(%rbp), %dl    movq    %rax, -72(%rbp)    movq    %rcx, -80(%rbp)    movb    %dl, -81(%rbp)    movq    -72(%rbp), %rax    movq    -80(%rbp), %rcx    movb    -81(%rbp), %dl    movq    %rax, -48(%rbp)    movq    %rcx, -56(%rbp)    movb    %dl, -57(%rbp)    movq    -48(%rbp), %rax    movq    %rax, -40(%rbp)    movq    -40(%rbp), %rcx    movq    %rcx, -32(%rbp)    movq    -32(%rbp), %rcx    movq    %rcx, -24(%rbp)    movq    -24(%rbp), %rcx    movq    %rcx, -16(%rbp)    movq    -56(%rbp), %rsi    movq    %rax, %rdi    movsbl    -57(%rbp), %edx    callq    __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEmc    leaq    -608(%rbp), %rax    movq    -504(%rbp), %rcx    movq    %rax, -200(%rbp)    movq    -200(%rbp), %rax    movq    %rax, -192(%rbp)    movq    -192(%rbp), %rax    movq    %rax, -184(%rbp)    movq    -184(%rbp), %rsi    movq    %rsi, -176(%rbp)    movq    -176(%rbp), %rsi    movq    %rsi, -168(%rbp)    movq    -168(%rbp), %rsi    movzbl    (%rsi), %edx    andl    $1, %edx    cmpl    $0, %edx    movq    %rcx, -656(%rbp)        ## 8-byte Spill    movq    %rax, -664(%rbp)        ## 8-byte Spill    je    LBB7_12## BB#11:    movq    -664(%rbp), %rax        ## 8-byte Reload    movq    %rax, -120(%rbp)    movq    -120(%rbp), %rcx    movq    %rcx, -112(%rbp)    movq    -112(%rbp), %rcx    movq    %rcx, -104(%rbp)    movq    -104(%rbp), %rcx    movq    16(%rcx), %rcx    movq    %rcx, -672(%rbp)        ## 8-byte Spill    jmp    LBB7_13LBB7_12:    movq    -664(%rbp), %rax        ## 8-byte Reload    movq    %rax, -160(%rbp)    movq    -160(%rbp), %rcx    movq    %rcx, -152(%rbp)    movq    -152(%rbp), %rcx    movq    %rcx, -144(%rbp)    movq    -144(%rbp), %rcx    addq    $1, %rcx    movq    %rcx, -136(%rbp)    movq    -136(%rbp), %rcx    movq    %rcx, -128(%rbp)    movq    -128(%rbp), %rcx    movq    %rcx, -672(%rbp)        ## 8-byte SpillLBB7_13:                                ## %_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4dataEv.exit    movq    -672(%rbp), %rax        ## 8-byte Reload    movq    %rax, -96(%rbp)    movq    -568(%rbp), %rcx    movq    -656(%rbp), %rdx        ## 8-byte Reload    movq    %rdx, -272(%rbp)    movq    %rax, -280(%rbp)    movq    %rcx, -288(%rbp)    movq    -272(%rbp), %rax    movq    (%rax), %rsi    movq    96(%rsi), %rsi    movq    -280(%rbp), %rdiLtmp68:    movq    %rdi, -680(%rbp)        ## 8-byte Spill    movq    %rax, %rdi    movq    -680(%rbp), %rax        ## 8-byte Reload    movq    %rsi, -688(%rbp)        ## 8-byte Spill    movq    %rax, %rsi    movq    %rcx, %rdx    movq    -688(%rbp), %rcx        ## 8-byte Reload    callq    *%rcxLtmp69:    movq    %rax, -696(%rbp)        ## 8-byte Spill    jmp    LBB7_14LBB7_14:                                ## %_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sputnEPKcl.exit    jmp    LBB7_15LBB7_15:    movq    -696(%rbp), %rax        ## 8-byte Reload    cmpq    -568(%rbp), %rax    je    LBB7_20## BB#16:    leaq    -328(%rbp), %rax    movq    %rax, -312(%rbp)    movq    $-1, -320(%rbp)    movq    -312(%rbp), %rax    movq    -320(%rbp), %rcx    movq    %rax, -296(%rbp)    movq    %rcx, -304(%rbp)    movq    -296(%rbp), %rax    movq    $0, (%rax)    movq    -328(%rbp), %rax    movq    %rax, -704(%rbp)        ## 8-byte Spill## BB#17:    leaq    -632(%rbp), %rax    movq    -704(%rbp), %rcx        ## 8-byte Reload    movq    %rcx, -632(%rbp)    movq    %rax, -336(%rbp)## BB#18:    movq    $0, -504(%rbp)    movq    -504(%rbp), %rax    movq    %rax, -496(%rbp)    movl    $1, -636(%rbp)    jmp    LBB7_21LBB7_19:Ltmp70:    movl    %edx, %ecx    movq    %rax, -616(%rbp)    movl    %ecx, -620(%rbp)Ltmp71:    leaq    -608(%rbp), %rdi    callq    __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1EvLtmp72:    jmp    LBB7_23LBB7_20:    movl    $0, -636(%rbp)LBB7_21:    leaq    -608(%rbp), %rdi    callq    __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev    movl    -636(%rbp), %eax    movl    %eax, %ecx    subl    $1, %ecx    movl    %eax, -708(%rbp)        ## 4-byte Spill    movl    %ecx, -712(%rbp)        ## 4-byte Spill    je    LBB7_29    jmp    LBB7_33LBB7_33:    movl    -708(%rbp), %eax        ## 4-byte Reload    testl    %eax, %eax    jne    LBB7_32    jmp    LBB7_22LBB7_22:    jmp    LBB7_24LBB7_23:    jmp    LBB7_30LBB7_24:    movq    -528(%rbp), %rax    movq    -520(%rbp), %rcx    subq    %rcx, %rax    movq    %rax, -576(%rbp)    cmpq    $0, -576(%rbp)    jle    LBB7_28## BB#25:    movq    -504(%rbp), %rax    movq    -520(%rbp), %rcx    movq    -576(%rbp), %rdx    movq    %rax, -352(%rbp)    movq    %rcx, -360(%rbp)    movq    %rdx, -368(%rbp)    movq    -352(%rbp), %rax    movq    (%rax), %rcx    movq    96(%rcx), %rcx    movq    -360(%rbp), %rsi    movq    -368(%rbp), %rdx    movq    %rax, %rdi    callq    *%rcx    cmpq    -576(%rbp), %rax    je    LBB7_27## BB#26:    leaq    -648(%rbp), %rax    leaq    -408(%rbp), %rcx    movq    %rcx, -392(%rbp)    movq    $-1, -400(%rbp)    movq    -392(%rbp), %rcx    movq    -400(%rbp), %rdx    movq    %rcx, -376(%rbp)    movq    %rdx, -384(%rbp)    movq    -376(%rbp), %rcx    movq    $0, (%rcx)    movq    -408(%rbp), %rcx    movq    %rcx, -648(%rbp)    movq    %rax, -416(%rbp)    movq    $0, -504(%rbp)    movq    -504(%rbp), %rax    movq    %rax, -496(%rbp)    jmp    LBB7_29LBB7_27:    jmp    LBB7_28LBB7_28:    movq    -536(%rbp), %rax    movq    %rax, -424(%rbp)    movq    $0, -432(%rbp)    movq    -424(%rbp), %rax    movq    24(%rax), %rcx    movq    %rcx, -440(%rbp)    movq    -432(%rbp), %rcx    movq    %rcx, 24(%rax)    movq    -504(%rbp), %rax    movq    %rax, -496(%rbp)LBB7_29:    movq    -496(%rbp), %rax    addq    $720, %rsp              ## imm = 0x2D0    popq    %rbp    retqLBB7_30:    movq    -616(%rbp), %rdi    callq    __Unwind_ResumeLBB7_31:Ltmp73:    movl    %edx, %ecx    movq    %rax, %rdi    movl    %ecx, -716(%rbp)        ## 4-byte Spill    callq    ___clang_call_terminateLBB7_32:    .cfi_endprocLeh_func_end7:    .section    __TEXT,__gcc_except_tab    .align    2GCC_except_table7:Lexception7:    .byte    255                     ## @LPStart Encoding = omit    .byte    155                     ## @TType Encoding = indirect pcrel sdata4    .asciz    "\274"                  ## @TType base offset    .byte    3                       ## Call site Encoding = udata4    .byte    52                      ## Call site table lengthLset43 = Leh_func_begin7-Leh_func_begin7 ## >> Call Site 1 <<    .long    Lset43Lset44 = Ltmp68-Leh_func_begin7         ##   Call between Leh_func_begin7 and Ltmp68    .long    Lset44    .long    0                       ##     has no landing pad    .byte    0                       ##   On action: cleanupLset45 = Ltmp68-Leh_func_begin7         ## >> Call Site 2 <<    .long    Lset45Lset46 = Ltmp69-Ltmp68                  ##   Call between Ltmp68 and Ltmp69    .long    Lset46Lset47 = Ltmp70-Leh_func_begin7         ##     jumps to Ltmp70    .long    Lset47    .byte    0                       ##   On action: cleanupLset48 = Ltmp71-Leh_func_begin7         ## >> Call Site 3 <<    .long    Lset48Lset49 = Ltmp72-Ltmp71                  ##   Call between Ltmp71 and Ltmp72    .long    Lset49Lset50 = Ltmp73-Leh_func_begin7         ##     jumps to Ltmp73    .long    Lset50    .byte    1                       ##   On action: 1Lset51 = Ltmp72-Leh_func_begin7         ## >> Call Site 4 <<    .long    Lset51Lset52 = Leh_func_end7-Ltmp72           ##   Call between Ltmp72 and Leh_func_end7    .long    Lset52    .long    0                       ##     has no landing pad    .byte    0                       ##   On action: cleanup    .byte    1                       ## >> Action Record 1 <<                                        ##   Catch TypeInfo 1    .byte    0                       ##   No further actions                                        ## >> Catch TypeInfos <<    .long    0                       ## TypeInfo 1    .align    2    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions    .globl    __ZN6MatrixC2Ed    .weak_def_can_be_hidden    __ZN6MatrixC2Ed    .align    4, 0x90__ZN6MatrixC2Ed:                        ## @_ZN6MatrixC2Ed    .cfi_startproc## BB#0:    pushq    %rbpLtmp81:    .cfi_def_cfa_offset 16Ltmp82:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp83:    .cfi_def_cfa_register %rbp    subq    $64, %rsp    movq    __ZNSt3__14coutE@GOTPCREL(%rip), %rax    leaq    L_.str2(%rip), %rsi    movq    %rdi, -24(%rbp)    movsd    %xmm0, -32(%rbp)    movq    -24(%rbp), %rdi    movq    %rdi, -48(%rbp)         ## 8-byte Spill    movq    %rax, %rdi    callq    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc    leaq    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_(%rip), %rsi    movq    %rax, -8(%rbp)    movq    %rsi, -16(%rbp)    movq    -8(%rbp), %rdi    callq    *-16(%rbp)    movl    $0, -36(%rbp)    movq    %rax, -56(%rbp)         ## 8-byte SpillLBB8_1:                                 ## =>This Loop Header: Depth=1                                        ##     Child Loop BB8_3 Depth 2    cmpl    $10, -36(%rbp)    jge    LBB8_8## BB#2:                                ##   in Loop: Header=BB8_1 Depth=1    movl    $0, -40(%rbp)LBB8_3:                                 ##   Parent Loop BB8_1 Depth=1                                        ## =>  This Inner Loop Header: Depth=2    cmpl    $10, -40(%rbp)    jge    LBB8_6## BB#4:                                ##   in Loop: Header=BB8_3 Depth=2    movsd    -32(%rbp), %xmm0    movslq    -40(%rbp), %rax    movslq    -36(%rbp), %rcx    imulq    $80, %rcx, %rcx    movq    -48(%rbp), %rdx         ## 8-byte Reload    addq    %rcx, %rdx    movsd    %xmm0, (%rdx,%rax,8)## BB#5:                                ##   in Loop: Header=BB8_3 Depth=2    movl    -40(%rbp), %eax    addl    $1, %eax    movl    %eax, -40(%rbp)    jmp    LBB8_3LBB8_6:                                 ##   in Loop: Header=BB8_1 Depth=1    jmp    LBB8_7LBB8_7:                                 ##   in Loop: Header=BB8_1 Depth=1    movl    -36(%rbp), %eax    addl    $1, %eax    movl    %eax, -36(%rbp)    jmp    LBB8_1LBB8_8:    addq    $64, %rsp    popq    %rbp    retq    .cfi_endproc    .section    __TEXT,__cstring,cstring_literalsL_.str:                                 ## @.str    .asciz    "Address of sum: "L_.str1:                                ## @.str1    .asciz    "Address of c:   "L_.str2:                                ## @.str2    .asciz    "Matrix::Matrix()"    .section    __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support.subsections_via_symbols

而这时简化版的代码(突出返回临时对象):

#include <iostream> #include <cstring>  using namespace std;   class Matrix  {  public:          explicit Matrix()  {  }           friend const Matrix operator+(const Matrix&, const Matrix&);   };   const Matrix operator+(const Matrix& arg1, const Matrix& arg2)  {          Matrix sum;          return sum; }   int main()  {          Matrix a,  b;        Matrix c = (a + b);           return 0;  } 

汇编:

    .section    __TEXT,__text,regular,pure_instructions    .globl    __ZplRK6MatrixS1_    .align    4, 0x90__ZplRK6MatrixS1_:                      ## @_ZplRK6MatrixS1_    .cfi_startproc## BB#0:    pushq    %rbpLtmp2:    .cfi_def_cfa_offset 16Ltmp3:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp4:    .cfi_def_cfa_register %rbp    subq    $32, %rsp    leaq    -8(%rbp), %rax    movq    %rdi, -16(%rbp)    movq    %rsi, -24(%rbp)    movq    %rax, %rdi    callq    __ZN6MatrixC1Ev    addq    $32, %rsp    popq    %rbp    retq    .cfi_endproc    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions    .globl    __ZN6MatrixC1Ev    .weak_def_can_be_hidden    __ZN6MatrixC1Ev    .align    4, 0x90__ZN6MatrixC1Ev:                        ## @_ZN6MatrixC1Ev    .cfi_startproc## BB#0:    pushq    %rbpLtmp7:    .cfi_def_cfa_offset 16Ltmp8:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp9:    .cfi_def_cfa_register %rbp    subq    $16, %rsp    movq    %rdi, -8(%rbp)    movq    -8(%rbp), %rdi    callq    __ZN6MatrixC2Ev    addq    $16, %rsp    popq    %rbp    retq    .cfi_endproc    .section    __TEXT,__text,regular,pure_instructions    .globl    _main    .align    4, 0x90_main:                                  ## @main    .cfi_startproc## BB#0:    pushq    %rbpLtmp12:    .cfi_def_cfa_offset 16Ltmp13:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp14:    .cfi_def_cfa_register %rbp    subq    $32, %rsp    leaq    -8(%rbp), %rdi    movl    $0, -4(%rbp)    callq    __ZN6MatrixC1Ev    leaq    -16(%rbp), %rdi    callq    __ZN6MatrixC1Ev    leaq    -8(%rbp), %rdi    leaq    -16(%rbp), %rsi    callq    __ZplRK6MatrixS1_    movl    $0, %eax    addq    $32, %rsp    popq    %rbp    retq    .cfi_endproc    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions    .globl    __ZN6MatrixC2Ev    .weak_def_can_be_hidden    __ZN6MatrixC2Ev    .align    4, 0x90__ZN6MatrixC2Ev:                        ## @_ZN6MatrixC2Ev    .cfi_startproc## BB#0:    pushq    %rbpLtmp17:    .cfi_def_cfa_offset 16Ltmp18:    .cfi_offset %rbp, -16    movq    %rsp, %rbpLtmp19:    .cfi_def_cfa_register %rbp    movq    %rdi, -8(%rbp)    popq    %rbp    retq    .cfi_endproc.subsections_via_symbols

 

一个函数返回临时对象引起的编译器优化问题