<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

    <title>P0120R0: constexpr unions and common initial sequences</title>
    <style type="text/css">
      p {text-align:justify}
      li {text-align:justify}
      blockquote.note
      {
      background-color:#E0E0E0;
      padding-left: 15px;
      padding-right: 15px;
      padding-top: 1px;
      padding-bottom: 1px;
      }
      ins, .inserted
      {
      color: black;
      background: #a0ffa0;
      text-decoration: underline;
      }
      del
      {
      color: black;
      background: #ffa0a0;
      text-decoration: line-through;
      }
    </style>
  </head><body>
    <table>
      <tr><td>Document Number:</td><td>P0120R0</td></tr>
      <tr><td>Date:</td><td>2015-09-25</td></tr>
      <tr><td>Author:</td><td><a href="mailto:anthony@justsoftwaresolutions.co.uk">Anthony
            Williams</a><br>Just Software Solutions Ltd</td></tr>
    </table>
    <h1>P0120R0: <code>constexpr</code> <code>union</code>s and common initial sequences</h1>

    <p>When prototyping my <code>variant</code> implementation, I found that the most
      space-efficient way of storing the values and discriminator was to create a union
      of <code>struct</code>s where each <code>struct</code> had the discriminator as the first
      field, and the data as the second field, rather than having a <code>struct</code> holding the
      discriminator and a <code>union</code> of the stored
      types. e.g. for <code>variant&lt;A,B&gt;</code> the storage was equivalent to:

      <pre>
        struct wrapped_A{
            char discriminator;
            A data;
        };
        struct wrapped_B{
            char discriminator;
            B data;
        };
        union storage{
            wrapped_A a;
            wrapped_B b;
        } u;
      </pre>

    <p>instead of</p>

    <pre>
      struct storage{
          char discriminator;
          union {
              A a;
              B b;
          } u;
      };
    </pre>

    <p>By 9.2 [class.mem] p18, it is OK to access the common initial sequence (the discriminator) of
        the union members, whichever member is active, so I could always
        read <code>u.a.discriminator</code> in order to check the stored type.</p>

      <p>This can be more space efficient than the alternative if the alignment on the largest field
        is less-strict than the alignment on another field. e.g. if <code>A</code> is
        a <code>struct</code> holding 5 <code>int</code>s, whereas <code>B</code> is a pointer,
        if <code>int</code>s are 4-byte aligned, but pointers are 8-byte aligned.</p>

    <p>Unfortunately, when I tried to make this <code>constexpr</code> correct, it didn't work: all
      the compilers I had complained that I was accessing a non-active <code>union</code> member if
      anything other than the first member was active.</p>

    <p>In the core reflector message 28016, Richard Smith confirmed that this is correct:</p>

      <blockquote>
Per [expr.const]/2.8, "A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
[...]
-- an lvalue-to-rvalue conversion (4.1) or modification (5.18, 5.2.6, 5.3.2) that is applied to a glvalue that
refers to a non-active member of a union or a subobject thereof;"
      </blockquote>

      <p>I think this is unfortunate, and don't see any need for this restriction. It is already
        allowed at runtime, so why not in <code>constexpr</code> expressions?</p>

    <p>By restricting the use of this in <code>constexpr</code> expressions people are forced to
    choose between being space-efficient and <code>constexpr</code>-compatible, which seems a poor
      choice to have to make.</p>

      <h2>Proposal</h2>

    <p>Modify [expr.const] paragraph 2 bullet 8 as follows:</p>

    <blockquote>
      &mdash; an lvalue-to-rvalue conversion (4.1) or modification (5.17, 5.2.6, 5.3.2) that is
applied to a glvalue that refers to a non-active member of a union or a subobject
thereof <ins>except that if a standard-layout union contains two or more standard-layout structs
that share a common initial sequence, and if the standard-layout union object currently contains one
of these standard-layout structs, it is permitted to inspect the common initial part of any of them
(see 9.2 [class.mem])</ins>;
    </blockquote>
      
</body></html>
