title: Does the standard require that std::array<T, 0> behave like it does not have trailing padding?
body: <p><code>std::array</code> is required by the standard to be well-defined even when the size is zero, so that <code>std::array&lt;T, 0&gt;</code> is well-defined even though <code>int[0]</code> is not allowed (though GCC implements an extension for it).</p>
  <p>However, on GCC, Clang, and MSVC, <code>std::array&lt;T, 0&gt;</code> is not treated as if it is a zero-sized struct, i.e. it does not act like it has trailing padding, and so <code>[[no_unique_address]]</code> and the empty base optimization does not work with it.  For example:</p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;array&gt;
  
  struct Tester {
      [[no_unique_address]] std::array&lt;char, 0&gt; arr;
      char c;
  };
  
  struct Tester2 : std::array&lt;char, 0&gt; {
      char c;
  };
  
  // true on GCC, Clang, and MSVC at least:
  static_assert(sizeof(Tester) == 2);
  static_assert(sizeof(Tester2) == 2);
  </code></pre>
  <p>This is surprising, since it's obviously implementable as an empty struct.  Is this something mandated by the standard?</p>
  <hr />
  <p>Note: I've looked into the code for libstdc++, and it works like this because <code>std::array&lt;char, 0&gt;</code> contains an instance of an empty struct that is not <code>[[no_unique_address]]</code> and not using empty base class optimization, i.e. it looks something like this:</p>
  <pre class="lang-cpp prettyprint-override"><code>template &lt;typename T&gt;
  struct array&lt;T, 0&gt; {
      struct {} empty; // no [[no_unique_address]]!
  };
  </code></pre>
  <p>But this doesn't doesn't explain <em>why</em> it was designed this way.  Even though <code>[[no_unique_address]]</code> wasn't a thing until C++20, the empty base class optimization is used liberally in other parts of the standard library, so it's definitely something that could be done if desired.</p>