union 'punning' structs w/ "common initial sequence": Why does C (99+), but not C++, stipulate a 'visible declaration of the union type'?
<h1>Background</h1>

<p>Discussions on the mostly un-or-implementation-defined nature of type-punning via a <code>union</code> typically quote the following bits, here via @ecatmur ( <a href="https://stackoverflow.com/a/31557852/2757035">https://stackoverflow.com/a/31557852/2757035</a> ), on an exemption for standard-layout <code>struct</code>s having a "common initial sequence" of member types:</p>

<blockquote>
  <p>C11 (<strong>6.5.2.3 Structure and union members</strong>; <strong>Semantics</strong>):</p>
  
  <blockquote>
    <p>[...] if a union contains several structures that share a common initial sequence (see below), and if the union object currently
    contains one of these structures, it is permitted to inspect the
    common initial part of any of them <strong>anywhere that a declaration of
    the completed type of the union is visible</strong>. Two structures share a
    <em>common initial sequence</em> if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or
    more initial members.</p>
  </blockquote>
  
  <p>C++03 (<strong>[class.mem]/16</strong>):</p>
  
  <blockquote>
    <p>If a POD-union contains two or more POD-structs that share a common initial sequence, and if the POD-union object currently contains one
    of these POD-structs, it is permitted to inspect the common initial
    part of any of them. Two POD-structs share a common initial sequence
    if corresponding members have layout-compatible types (and, for
    bit-fields, the same widths) for a sequence of one or more initial
    members.</p>
  </blockquote>
  
  <p>Other versions of the two standards have similar language; since C++11
  the terminology used is <em>standard-layout</em> rather than <em>POD</em>.</p>
</blockquote>

<p>Since no reinterpretation is required, this isn't really type-punning, just name substitution applied to <code>union</code> member accesses. A proposal for C++17 (the infamous P0137R1) makes this explicit using language like 'the access is as if the other struct member was nominated'.</p>

<p>But please note the bold - "<strong>anywhere that a declaration of the completed type of the union is visible</strong>" - a clause that exists in C11 but nowhere in C++ drafts for 2003, 2011, or 2014 (all nearly identical, but later versions replace "POD" with the new term <em>standard layout</em>). In any case, the 'visible declaration of <code>union</code> type bit is totally absent in the corresponding section of any C++ standard.</p>

<p>@loop and @Mints97, here - <a href="https://stackoverflow.com/a/28528989/2757035">https://stackoverflow.com/a/28528989/2757035</a> - show that this line was also <strong>absent in C89, first appearing in C99</strong> and remaining in C since then (though, again, never filtering through to C++).</p>

<h1>Standards discussions around this</h1>

<p>[snipped - see my answer]</p>

<h1>Questions</h1>

<p>From this, then, my questions were:</p>

<ul>
<li><p><strong>What does this mean?</strong> What is classed as a 'visible declaration'? Was this clause intended to narrow down - or expand up - the range of contexts in which such 'punning' has defined behaviour?</p></li>
<li><p><strong>Are we to assume that this omission in C++ is very deliberate?</strong></p></li>
<li><p><strong>What is the reason for C++ differing from C?</strong> Did C++ just 'inherit' this from C89 and then either decide - or worse, <em>forget</em> - to update alongside C99?</p></li>
<li><p>If the difference is intentional, then <strong>what benefits or drawbacks are there to the 2 different treatments in C vs C++?</strong></p></li>
<li><p><strong>What, if any, interesting ramifications does it have at compile- or runtime?</strong> For example, @ecatmur, in a comment replying to my pointing this out on his original answer (link as above), speculated as follows.</p></li>
</ul>

<blockquote>
  <p>I'd imagine it permits more aggressive optimization; C can assume that
  function arguments <code>S* s</code> and <code>T* t</code> do not alias even if they share a
  common initial sequence as long as no <code>union { S; T; }</code> is in view,
  while C++ can make that assumption only at link time. Might be worth
  asking a separate question about that difference.</p>
</blockquote>

<p>Well, here I am, asking! I'm very interested in any thoughts about this, especially: other relevant parts of the (either) Standard, quotes from committee members or other esteemed commentators, insights from developers who might have noticed a practical difference due to this - assuming any compiler even <em>bothers</em> to enforce C's added clause - and etc. The aim is to generate a useful catalogue of relevant facts about this C clause and its (intentional or not) omission from C++. So, let's go!</p>