title: Initializing base part of the derived struct / Unexpected packing derived struct fields to alignment gap of the base struct
body: <p>It was unexpectedly discovered, that clang++7 allows itself to tightly pack fields of the derived struct (struct "B" with field "B::u16_gap" in the example below) to the alignment gap of the base struct (struct "A"). But function "zero_init" in the example expects it's input to be the "A"-object with non-used alignment gap, so it can be overwritten by "memcpy". This function "zero_init", of course, overwrites any value of the "B::u16_gap"-field, when applied to "B"-object.</p>
  
  <pre><code>// compilation: clang++-7 -std=c++17 test.cpp
  #include &lt;cstdint&gt;
  #include &lt;cstring&gt;
  #include &lt;iostream&gt;
  
  struct A {
      std::uint32_t u32 = 0;
      std::uint16_t u16 = 0;
  };
  
  void zero_init(A&amp; a) {
      static constexpr A zero = {};
      std::memcpy(&amp;a, &amp;zero, sizeof(A));
  };
  
  struct B: public A {
      std::uint16_t u16_gap = 0;
  };
  
  static_assert(sizeof(A) == 8);
  static_assert(sizeof(B) == 8); // clang++-7 packs additional field "B::u16_gap" to the alignment gap of the A (for g++-7 it is not true)
  
  int main() {
      B b;
      A&amp; a = b;
      b.u16_gap = 123;
      zero_init(a);
      std::cout &lt;&lt; b.u16_gap &lt;&lt; std::endl; // writes "0" instead of expected "123"
  }
  </code></pre>
  
  <p>Where is the ill-formed part (deviation from "well behavior" rules of the C++17 standard) in this code?</p>