title: Standard-layout and tail padding
body: <p>David Hollman recently tweeted the following example (which I've slightly reduced):</p>
  
  <pre><code>struct FooBeforeBase {
      double d;
      bool b[4];
  };
  
  struct FooBefore : FooBeforeBase {
      float value;
  };
  
  static_assert(sizeof(FooBefore) &gt; 16);
  
  //----------------------------------------------------
  
  struct FooAfterBase {
  protected:
      double d;
  public:  
      bool b[4];
  };
  
  struct FooAfter : FooAfterBase {
      float value;
  };
  
  static_assert(sizeof(FooAfter) == 16);
  </code></pre>
  
  <p>You can examine the layout <a href="https://godbolt.org/z/RivQ7z" rel="noreferrer">in clang on godbolt</a> and see that the reason the size changed is that in <code>FooBefore</code>, the member <code>value</code> is placed at offset 16 (maintaining a full alignment of 8 from <code>FooBeforeBase</code>) whereas in <code>FooAfter</code>, the member <code>value</code> is placed at offset 12 (effectively using <code>FooAfterBase</code>'s tail-padding).</p>
  
  <p>It is clear to me that <code>FooBeforeBase</code> is standard-layout, but <code>FooAfterBase</code> is not (because its non-static data members do not all have the same access control, <a href="http://eel.is/c++draft/class#prop-3.3" rel="noreferrer">[class.prop]/3</a>). But what is it about <code>FooBeforeBase</code>'s being standard-layout that requires this respect of padding bytes? </p>
  
  <p>Both gcc and clang reuse <code>FooAfterBase</code>'s padding, ending up with <code>sizeof(FooAfter) == 16</code>. But MSVC does not, ending up with 24. Is there a required layout per the standard and, if not, why do gcc and clang do what they do?</p>
  
  <hr />
  
  <p>There is some confusion, so just to clear up:</p>
  
  <ul>
  <li><code>FooBeforeBase</code> is standard-layout</li>
  <li><code>FooBefore</code> is <em>not</em> (both it and a base class have non-static data members, similar to <code>E</code> in <a href="http://eel.is/c++draft/class#prop-4" rel="noreferrer">this example</a>)</li>
  <li><code>FooAfterBase</code> is <em>not</em> (it has non-static data members of differing access)</li>
  <li><code>FooAfter</code> is <em>not</em> (for both of the above reasons)</li>
  </ul>