title: Packing non-POD type: no warning, unexpected size?
body: <p>Here is a rather contrived series of types. <code>A2</code> is just a non-POD version of <code>A</code>:</p>
  
  <pre><code>template &lt;size_t N&gt;
  struct A { 
      char data[N];
  } __attribute__((packed));
  
  template &lt;size_t N&gt;
  struct A2 {
      A2() { // actual body not significant
          memset(data, 0, N); 
      }   
  
      char data[N];
  } __attribute__((packed));
  
  template &lt;template &lt;size_t&gt; class T&gt;
  struct C { 
      T&lt;9&gt; a;
      int32_t i;
      T&lt;11&gt; t2; 
  } __attribute__((packed));
  //}; // oops, forgot to pack
  
  template &lt;template &lt;size_t&gt; class T&gt;
  struct B : C&lt;T&gt; {
      char footer;
  } __attribute__((packed));
  </code></pre>
  
  <p>As-is, <code>sizeof(B&lt;A&gt;)</code> == <code>sizeof(B&lt;A2&gt;)</code> == 25. I get no warnings compiling with -Wall -pedantic (this is gcc 4.9.0). </p>
  
  <p>But now, let's say I forgot to pack <code>C</code>. Now I get:</p>
  
  <pre><code>sizeof(B&lt;A&gt;) == 32
  sizeof(B&lt;A2&gt;) == 28
  </code></pre>
  
  <p>Still no warnings. What happened here? How is <code>B&lt;A2&gt;</code> smaller than <code>B&lt;A&gt;</code>? Is this just undefined behavior due to <code>A2</code> not being POD? </p>
  
  <p>If I reorganize <code>B</code> to look have a <code>C&lt;T&gt;</code> member instead of inheriting from it, <em>then</em> and only then do I get a warning:</p>
  
  <blockquote>
    <p>ignoring packed attribute because of unpacked non-POD field ‘C B::c’</p>
  </blockquote>
  
  <p>[Update] In response to IdeaHat's comments, here are some other the offsets:</p>
  
  <pre><code>        B&lt;A&gt;  B&lt;A2&gt;
  a       0     0
  i       12    12
  t2      16    16
  footer  28    27
  </code></pre>
  
  <p>And </p>
  
  <pre><code>sizeof(C&lt;A&gt;) == 28
  sizeof(C&lt;A2&gt;) == 28
  </code></pre>
  
  <p>[Update 2] I see the same behavior on clang with respect to the offsets, except that <code>sizeof(B&lt;A&gt;)</code> is 29 instead of 32. </p>