title: What are the strict aliasing rules when casting *from* a char array?
body: <p>I'm confused by the strict aliasing rules when it comes to casting a char array to other types. I know that it is permitted to cast any object <em>to</em> a char array, but I'm not sure what happens the other way around.</p>
  
  <p>Take a look at this:</p>
  
  <pre><code>#include &lt;type_traits&gt;
  
  using namespace std;
  
  struct{
      alignas (int) char buf[sizeof(int)]; //correct?
  } buf1;
  
  alignas(int) char buf2[sizeof(int)]; //incorrect?
  
  struct{
      float f; //obviously incorrect
  } buf3;
  
  typename std::aligned_storage&lt;sizeof(int), alignof(int)&gt;::type buf4; //obviously correct
  
  int main()
  {
      reinterpret_cast&lt;int&amp;&gt;(buf1) = 1;
      *reinterpret_cast&lt;int*&gt;(buf2) = 1;
      reinterpret_cast&lt;int&amp;&gt;(buf3) = 1;
      reinterpret_cast&lt;int&amp;&gt;(buf4) = 1;
  }
  </code></pre>
  
  <p>Compiling using g++-5.3.0 results in warnings only on the second and third line of main:</p>
  
  <pre><code>$ g++ -fsyntax-only -O3 -std=c++14 -Wall main.cpp 
  main.cpp: In function ‘int main()’:
  main.cpp:25:30: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
    *reinterpret_cast&lt;int*&gt;(buf2) = 1;
                                ^
  main.cpp:26:29: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
    reinterpret_cast&lt;int&amp;&gt;(buf3) = 1;
                               ^
  </code></pre>
  
  <p>Is gcc correct in that lines 1 and 4 are correct, while lines 2 and 3 are not? I'm fairly sure line 4 is correct (that's what <code>aligned_storage</code> is for), but what are the rules at play here?</p>