title: Explicitly defaulted copy ctor generates better code than hand written equivalent
body: <p>I am seeing a difference in generated code depending on whether I <em>explicitly default</em> the copy constructor, or <em>hand-write</em> the same thing.  It's a simple class that only holds an int and defines some arithmetic operators on it.</p>
  
  <p>Both clang and g++ handle this situation in similar ways, so it made me wonder if there is an underlying language requirement for this, and if so, what's it doing?  Looking for citations in the standard if possible.  :)</p>
  
  <p>To show this in action, I wrote the average() function two ways, operating on raw <em>ints</em> and also on <em>Holders</em>.  I expected the two to generate the same code.  Here is the output:</p>
  
  <p><em>Explicitly defaulted copy constructor:</em></p>
  
  <pre><code>average(Holder, Holder):
    add esi, edi
    mov eax, esi
    shr eax, 31
    add eax, esi
    sar eax
    ret
  average(int, int):
    add esi, edi
    mov eax, esi
    shr eax, 31
    add eax, esi
    sar eax
    ret
  </code></pre>
  
  <p>It <em>is</em> the same!  Awesome, right?  The question arises when I forget to "default" the implementation, and simply hand-write the version.  Up until now I was under the impression that this should have the same resulting code as the defaulted code, but it doesn't.</p>
  
  <p><em>hand written copy constructor</em></p>
  
  <pre><code>average(Holder, Holder):
    mov edx, DWORD PTR [rdx]
    mov ecx, DWORD PTR [rsi]
    mov rax, rdi
    add ecx, edx
    mov edx, ecx
    shr edx, 31
    add edx, ecx
    sar edx
    mov DWORD PTR [rdi], edx
    ret
  average(int, int):
    add esi, edi
    mov eax, esi
    shr eax, 31
    add eax, esi
    sar eax
    ret
  </code></pre>
  
  <p>I'm trying to understand the reason for this, and relevant <em>citations from the standard</em> are most appreciated.</p>
  
  <p>Here is the code</p>
  
  <pre><code>#define EXPLICITLY_DEFAULTED_COPY_CTOR true
  
  class Holder {
  public:
  
  #if EXPLICITLY_DEFAULTED_COPY_CTOR
      Holder(Holder const &amp; other) = default;
  #else
      Holder(Holder const &amp; other) noexcept : value{other.value} { }
  #endif 
      constexpr explicit Holder(int value) noexcept : value{value} {}
  
      Holder&amp; operator+=(Holder rhs) { value += rhs.value; return *this; } 
      Holder&amp; operator/=(Holder rhs) { value /= rhs.value; return *this; } 
      friend Holder operator+(Holder lhs, Holder rhs) { return lhs += rhs; }
      friend Holder operator/(Holder lhs, Holder rhs) { return lhs /= rhs; }    
  
  private:
      int value;
  };
  
  Holder average(Holder lhs, Holder rhs) {
      return (lhs + rhs) / Holder{2};
  }
  
  int average(int lhs, int rhs) {
      return (lhs + rhs) / int{2};
  }
  </code></pre>
  
  <p>If this is expected, then is there anything I can do to the hand-written implementation that will get it to generate the same code as the defaulted version?  I thought noexcept might help, but it doesn't.</p>
  
  <p>Notes:
  If I add move constructor, the same issue remains except this difference happens with it instead of the copy constructor.  It's the underlying <em>reason</em> I'm seeking, not just workarounds.  I'm not interested in a code review or comments on style that are not directly relevant to answering why the code generation is different, because this is heavily minimized to show the issue I'm asking about.</p>
  
  <p>See it live on Godbolt:  <a href="https://godbolt.org/g/YA5Zsq" rel="noreferrer">https://godbolt.org/g/YA5Zsq</a></p>