title: Is memcpy of a trivially-copyable type construction or assignment?
body: <p>Let's say you have an object of type <code>T</code> and a suitably-aligned memory buffer <code>alignas(T) unsigned char[sizeof(T)]</code>.  If you use <code>std::memcpy</code> to copy from the object of type <code>T</code> to the <code>unsigned char</code> array, is that considered copy construction or copy-assignment?</p>
  
  <p>If a type is trivially-copyable but not standard-layout, it is conceivable that a class such as this:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>struct Meow
  {
      int x;
  protected: // different access-specifier means not standard-layout
      int y;
  };
  </code></pre>
  
  <p>could be implemented like this, because the compiler isn't forced into using standard-layout:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>struct Meow_internal
  {
  private:
      ptrdiff_t x_offset;
      ptrdiff_t y_offset;
      unsigned char buffer[sizeof(int) * 2 + ANY_CONSTANT];
  };
  </code></pre>
  
  <p>The compiler could store <code>x</code> and <code>y</code> of Meow within buffer at any portion of <code>buffer</code>, possibly even at a random offset within <code>buffer</code>, so long as they are aligned properly and do not overlap.  The offset of <code>x</code> and <code>y</code> could even vary randomly with each construction if the compiler wishes.  (<code>x</code> could go after <code>y</code> if the compiler wishes because the Standard only requires members of the same access-specifier to go in order, and <code>x</code> and <code>y</code> have different access-specifiers.)</p>
  
  <p>This would meet the requirements of being trivially-copyable; a <code>memcpy</code> would copy the hidden offset fields, so the new copy would work.  But some things would not work.  For example, holding a pointer to <code>x</code> across a <code>memcpy</code> would break:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>Meow a;
  a.x = 2;
  a.y = 4;
  int *px = &amp;a.x;
  
  Meow b;
  b.x = 3;
  b.y = 9;
  std::memcpy(&amp;a, &amp;b, sizeof(a));
  
  ++*px; // kaboom
  </code></pre>
  
  <p>However, is the compiler really allowed to implement a trivially-copyable class in this manner?  Dereferencing <code>px</code> should only be undefined behavior if <code>a.x</code>'s lifetime has ended.  Has it?  The relevant portions of the N3797 draft Standard aren't very clear on the subject.  This is section <strong>[basic.life]/1</strong>:</p>
  
  <blockquote>
    <p>The <em>lifetime</em> of an object is a runtime property of the object.  An
    object is said to have non-trivial initialization if it is of a class
    or aggregate type and it or one of its members is initialized by a
    constructor other than a trivial default constructor.  [ <em>Note:</em>
    initialization by a trivial copy/move constructor is non-trivial
    initialization. — <em>end note</em> ] The lifetime of an object of type <code>T</code>
    begins when:</p>
    
    <ul>
    <li>storage with the proper alignment and size for type <code>T</code> is obtained, and</li>
    <li>if the object has non-trivial initialization, its initialization is complete.</li>
    </ul>
    
    <p>The lifetime of an object of type <code>T</code> ends when:</p>
    
    <ul>
    <li>if <code>T</code> is a class type with a non-trivial destructor (<strong>[class.dtor]</strong>), the destructor call starts, or</li>
    <li>the storage which the object occupies is reused or released.</li>
    </ul>
  </blockquote>
  
  <p>And this is <strong>[basic.types]/3</strong>:</p>
  
  <blockquote>
    <p>For any object (other than a base-class subobject) of trivially
    copyable type <code>T</code>, whether or not the object holds a valid value of
    type <code>T</code>, the underlying bytes (<strong>[intro.memory]</strong>) making up the
    object can be copied into an array of <code>char</code> or <code>unsigned char</code>.  If
    the content of the array of <code>char</code> or <code>unsigned char</code> is copied back
    into the object, the object shall subsequently hold its original
    value.  <em>example omitted</em></p>
  </blockquote>
  
  <p>The question then becomes, is a <code>memcpy</code> overwrite of a trivially-copyable class instance "copy construction" or "copy-assignment"?  The answer to the question seems to decide whether <code>Meow_internal</code> is a valid way for a compiler to implement trivially-copyable class <code>Meow</code>.</p>
  
  <p>If <code>memcpy</code> is "copy construction", then the answer is that <code>Meow_internal</code> is valid, because copy construction is reusing the memory.  If <code>memcpy</code> is "copy-assignment", then the answer is that <code>Meow_internal</code> is not a valid implementation, because assignment does not invalidate pointers to the instantiated members of a class.  If <code>memcpy</code> is both, I have no idea what the answer is.</p>