<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 588: requirements on zero sized tr1::arrays and other details</title>
<meta property="og:title" content="Issue 588: requirements on zero sized tr1::arrays and other details">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue588.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#NAD">NAD</a> status.</em></p>
<h3 id="588"><a href="lwg-closed.html#588">588</a>. requirements on zero sized <code>tr1::arrays</code> and other details</h3>
<p><b>Section:</b> 23.3.3 <a href="https://wg21.link/array">[array]</a> <b>Status:</b> <a href="lwg-active.html#NAD">NAD</a>
 <b>Submitter:</b> Gennaro Prota <b>Opened:</b> 2006-07-18 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#array">issues</a> in [array].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The wording used for section 23.2.1 [lib.array] seems to be subtly
ambiguous about zero sized arrays (N==0). Specifically:
</p>
<p>
* "An instance of array&lt;T, N&gt; stores N elements of type T, so that
[...]"
</p>
<p>
Does this imply that a zero sized array object stores 0 elements, i.e.
that it cannot store any element of type T? The next point clarifies
the rationale behind this question, basically how to implement begin()
and end():
</p>
<p>
* 23.2.1.5 [lib.array.zero], p2: "In the case that N == 0, begin() ==
end() == unique value."
</p>
<p>
What does "unique" mean in this context? Let's consider the following
possible implementations, all relying on a partial specialization:
</p>
<blockquote><pre>
a)
    template&lt; typename T &gt;
    class array&lt; T, 0 &gt; {
    
        ....

        iterator begin()
        { return iterator( reinterpret_cast&lt; T * &gt;( this ) ); }
        ....

    };
</pre></blockquote>
<p>
This has been used in boost, probably intending that the return value
had to be unique to the specific array object and that array couldn't
store any T. Note that, besides relying on a reinterpret_cast, has
(more than potential) alignment problems.
</p>
<blockquote><pre>
b)
    template&lt; typename T &gt;
    class array&lt; T, 0 &gt; {
    
        T t;

        iterator begin()
        { return iterator( &amp;t ); }
        ....

    };
</pre></blockquote>
<p>
This provides a value which is unique to the object and to the type of
the array, but requires storing a T. Also, it would allow the user to
mistakenly provide an initializer list with one element.
</p>
<p>
A slight variant could be returning *the* null pointer of type T
</p>
<blockquote><pre>
    return static_cast&lt;T*&gt;(0);
</pre></blockquote>
<p>
In this case the value would be unique to the type array&lt;T, 0&gt; but not
to the objects (all objects of type array&lt;T, 0&gt; with the same value
for T would yield the same pointer value).
</p>
<p>
Furthermore this is inconsistent with what the standard requires from
allocation functions (see library issue 9).
</p>
<p>
c) same as above but with t being a static data member; again, the
value would be unique to the type, not to the object.
</p>
<p>
d) to avoid storing a T *directly* while disallowing the possibility
to use a one-element initializer list a non-aggregate nested class
could be defined
</p>
<blockquote><pre>
    struct holder { holder() {} T t; } h;
</pre></blockquote>
<p>
and then begin be defined as
</p>
<blockquote><pre>
 iterator begin() { return &amp;h.t; }
</pre></blockquote>
<p>
But then, it's arguable whether the array stores a T or not.
Indirectly it does.
</p>
<p>
-----------------------------------------------------
</p>
<p>
Now, on different issues:
</p>
<p>
* what's the effect of calling assign(T&amp;) on a zero-sized array? There
seems to be only mention of front() and back(), in 23.2.1 [lib.array]
p4 (I would also suggest to move that bullet to section 23.2.1.5
[lib.array.zero], for locality of reference)
</p>
<p>
* (minor) the opening paragraph of 23.2.1 [lib.array] wording is a bit
inconsistent with that of other sequences: that's not a problem in
itself, but compare it for instance with "A vector is a kind of
sequence that supports random access iterators"; though the intent is
obvious one might argue that the wording used for arrays doesn't tell
what an array is, and relies on the reader to infer that it is what
the &lt;array&gt; header defines.
</p>
<p>
* it would be desiderable to have a static const data member of type
std::size_t, with value N, for usage as integral constant expression
</p>
<p>
* section 23.1 [lib.container.requirements] seem not to consider
fixed-size containers at all, as it says: "[containers] control
allocation and deallocation of these objects [the contained objects]
through constructors, destructors, *insert and erase* operations"
</p>
<p>
* max_size() isn't specified: the result is obvious but, technically,
it relies on table 80: "size() of the largest possible container"
which, again, doesn't seem to consider fixed size containers
</p>

<p><i>[
2009-05-29 Daniel adds:
]</i></p>


<blockquote>
<ol style="list-style-type:lower-alpha">
<li>
<p>
star bullet 1 ("what's the effect of calling <code>assign(T&amp;)</code> on a
zero-sized array?[..]");
</p>
<blockquote><p>
<code>assign</code> has been renamed to <code>fill</code> and the semantic of <code>fill</code> is now
defined in terms of
the free algorithm <code>fill_n</code>, which is well-defined for this situation.
</p></blockquote>
</li>
<li>
<p>
star bullet 3 ("it would be desiderable to have a static const data
member..."):
</p>
<blockquote><p>
It seems that <code>tuple_size&lt;array&lt;T, N&gt; &gt;::value</code> as of 23.3.3.7 <a href="https://wg21.link/array.tuple">[array.tuple]</a> does
provide this functionality now.
</p></blockquote>
</li>
</ol>
</blockquote>

<p><i>[
2009-07 Frankfurt
]</i></p>


<blockquote>
<p>
Alisdair to address by the next meeting, or declare NAD.
</p>
<p>
Moved to Tentatively NAD.
</p>
</blockquote>

<p><i>[
2009 Santa Cruz:
]</i></p>


<blockquote><p>
Moved to NAD.
</p></blockquote>



<p id="res-588"><b>Proposed resolution:</b></p>
<p>
</p>


<p><i>[
Kona (2007): requirements on zero sized <code>tr1::array</code>s and other details
Issue 617: <code>std::array</code> is a sequence that doesn't satisfy the sequence
requirements? Alisdair will prepare a paper. Proposed Disposition: Open
]</i></p>





</body>
</html>
