title: technical legality of incompatible pointer assignments
body: <p>The C11 standard ISO/IEC 9899:2011 (E) states the following constraints for simple assignments in §6.5.16.1/1:</p>
  
  <blockquote>
    <p>One of the following shall hold:</p>
    
    <ul>
    <li>the left operand has atomic, qualified, or unqualified arithmetic type, and the right has
    arithmetic type;</li>
    <li>the left operand has an atomic, qualified, or unqualified version of a structure or union
    type compatible with the type of the right;</li>
    <li>the left operand has atomic, qualified, or unqualified pointer type, and (considering
    the type the left operand would have after lvalue conversion) both operands are
    pointers to qualified or unqualified versions of compatible types, and the type pointed
    to by the left has all the qualifiers of the type pointed to by the right;</li>
    <li>the left operand has atomic, qualified, or unqualified pointer type, and (considering
    the type the left operand would have after lvalue conversion) one operand is a pointer
    to an object type, and the other is a pointer to a qualified or unqualified version of
    void, and the type pointed to by the left has all the qualifiers of the type pointed to
    by the right;</li>
    <li>the left operand is an atomic, qualified, or unqualified pointer, and the right is a null
    pointer constant; or</li>
    <li>the left operand has type atomic, qualified, or unqualified <code>_Bool</code>, and the right is a pointer.</li>
    </ul>
  </blockquote>
  
  <p>I am interested in the case in which both sides are pointers to <em>incompatible</em> types different from <code>void</code>. If I understand correctly, this should at the very least invoke UB, as it violates this constraint. One example for incompatible types should be (according to §6.2.7 and §6.7.2) <code>int</code> and <code>double</code>.</p>
  
  <p>Therefore the following program should be in violation:</p>
  
  <pre><code>int main(void) {
    int a = 17;
    double* p;
    p = &amp;a;
    (void)p;
  }
  </code></pre>
  
  <p>Both gcc and clang warn about "-Wincompatible-pointer-types", but do not abort compilation (compilation with <code>-std=c11 -Wall -Wextra -pedantic</code>).</p>
  
  <p>Similarly, the following program only leads to a "-Wint-conversion" warning, while compiling just fine.</p>
  
  <pre><code>int main(void) {
    int a;
    double* p;
    p = a;
    (void)p;
  }
  </code></pre>
  
  <p>Coming from C++, I expected that either of those test cases would require a cast to compile. Is there any reason why either of the programs would be standards-legal? Or, are there at least significant historic reasons for supporting this code style even when disabling the entertaining GNU C extensions by explicitly using <code>-std=c11</code> instead of <code>-std=gnu11</code>?</p>