title: Is the strict aliasing rule incorrectly specified?
body: <p>As <a href="https://stackoverflow.com/q/38784268/417501">previously established</a>, a union of the form</p>
  
  <pre><code>union some_union {
      type_a member_a;
      type_b member_b;
      ...
  };
  </code></pre>
  
  <p>with <em>n</em> members comprises <em>n</em> + 1 objects in overlapping storage: One object for the union itself and one object for each union member. It is clear, that you may freely read and write to any union member in any order, even if reading a union member that was not the last one written to. The strict aliasing rule is never violated, as the lvalue through which you access the storage has the correct effective type.</p>
  
  <p>This is <a href="https://stackoverflow.com/a/33633460/417501">further supported</a> by footnote 95, which explains how type punning is an intended use of unions.</p>
  
  <p>A typical example of the optimizations enabled by the <em>strict aliasing rule</em> is this function:</p>
  
  <pre><code>int strict_aliasing_example(int *i, float *f)
  {
      *i = 1;
      *f = 1.0;
      return (*i);
  }
  </code></pre>
  
  <p>which the compiler may optimize to something like</p>
  
  <pre><code>int strict_aliasing_example(int *i, float *f)
  {
      *i = 1;
      *f = 1.0;
      return (1);
  }
  </code></pre>
  
  <p>because it can safely assume that the write to <code>*f</code> does not affect the value of <code>*i</code>.</p>
  
  <p>However, what happens when we pass two pointers to members of the same union? Consider this example, assuming a typical platform where <code>float</code> is an IEEE 754 single precision floating point number and <code>int</code> is a 32 bit two's complement integer:</p>
  
  <pre><code>int breaking_example(void)
  {
      union {
          int i;
          float f;
      } fi;
  
      return (strict_aliasing_example(&amp;fi.i, &amp;fi.f));
  }
  </code></pre>
  
  <p>As previously established, <code>fi.i</code> and <code>fi.f</code> refer to an overlapping memory region. Reading and writing them is unconditionally legal (writing is only legal once the union has been initialized) in any order. In my opinion, the previously discussed optimization performed by all major compilers yields incorrect code as the two pointers of different type legally point to the same location.</p>
  
  <p>I somehow can't believe that my interpretation of the strict aliasing rule is correct. It doesn't seem plausible that the very optimization the strict aliasing was designed for is not possible due to the aforementioned corner case.</p>
  
  <p>Please tell me why I'm wrong.</p>
  
  <p>A <a href="https://stackoverflow.com/q/38452208/417501">related question</a> turned up during research.</p>
  
  <p><em>Please read all existing answers and their comments before adding your own to make sure that your answer adds a new argument.</em></p>