<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 624: valarray assignment and arrays of unequal length</title>
<meta property="og:title" content="Issue 624: valarray assignment and arrays of unequal length">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue624.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#CD1">CD1</a> status.</em></p>
<h3 id="624"><a href="lwg-defects.html#624">624</a>. <code>valarray</code> assignment and arrays of unequal length</h3>
<p><b>Section:</b> 29.6.2.3 <a href="https://wg21.link/valarray.assign">[valarray.assign]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Martin Sebor <b>Opened:</b> 2007-01-20 <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#valarray.assign">issues</a> in [valarray.assign].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
        <p>

The behavior of the  <code>valarray</code> copy assignment operator is
defined only when both sides have  the same number of elements and the
spec is explicit about assignments of arrays of unequal lengths having
undefined behavior.

        </p>
        <p>

However, the generalized  subscripting assignment operators overloaded
on <code>slice_array</code>  et al (29.6.2.3 <a href="https://wg21.link/valarray.assign">[valarray.assign]</a>)  don't have any
such restriction, leading  the reader to believe that  the behavior of
these  overloads is  well defined  regardless  of the  lengths of  the
arguments.

        </p>
        <p>

For example,  based on  the reading  of the spec  the behavior  of the
snippet below can be expected to be well-defined:

        </p>
        <pre>
    const std::slice from_0_to_3 (0, 3, 1);   // refers to elements 0, 1, 2
    const std::valarray&lt;int&gt; a (1, 3);        // a = { 1, 1, 1 }
    std::valarray&lt;int&gt;       b (2, 4);        // b = { 2, 2, 2, 2 }

    b = a [from_0_to_3];
        </pre>
        <p>

In practice, <code>b</code> may end up being <code>{ 1, 1, 1 }</code>,
<code>{  1,  1, 1,  2  }</code>,  or  anything else,  indicating  that
existing implementations vary.

        </p>

<p>
Quoting from Section 3.4, Assignment operators, of Al Vermeulen's
Proposal for Standard C++ Array Classes (see c++std-lib-704;
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0308.asc">N0308</a>):
</p>
<blockquote><p>
  ...if the size of the array on the right hand side of the equal
  sign differs from the size of the array on the left, a run time
  error occurs. How this error is handled is implementation
  dependent; for compilers which support it, throwing an exception
  would be reasonable.
</p></blockquote>

<p>
And see more history in
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/1993/N0280.pdf">N0280</a>.
</p>

        <p>

It has  been argued in  discussions on the committee's  reflector that
the semantics of all <code>valarray</code> assignment operators should
be permitted to be undefined unless  the  length  of the arrays  being
assigned is the same as the length of the one being assigned from. See
the thread starting at c++std-lib-17786.

        </p>
        <p>

In order  to reflect  such views, the  standard must specify  that the
size of the  array referred to by the argument  of the assignment must
match the size of the array  under assignment, for example by adding a
<i>Requires</i> clause to 29.6.2.3 <a href="https://wg21.link/valarray.assign">[valarray.assign]</a> as follows:

        </p>
        <blockquote><p>

<i>Requires</i>: The length of the  array to which the argument refers
equals <code>size()</code>.

        </p></blockquote>

        <p>

Note that it's  far from clear that such leeway  is necessary in order
to implement <code>valarray</code> efficiently.

        </p>


<p id="res-624"><b>Proposed resolution:</b></p>
<p>
Insert new paragraph into 29.6.2.3 <a href="https://wg21.link/valarray.assign">[valarray.assign]</a>:
</p>

<blockquote>
<pre>
valarray&lt;T&gt;&amp; operator=(const slice_array&lt;T&gt;&amp;); 
valarray&lt;T&gt;&amp; operator=(const gslice_array&lt;T&gt;&amp;); 
valarray&lt;T&gt;&amp; operator=(const mask_array&lt;T&gt;&amp;); 
valarray&lt;T&gt;&amp; operator=(const indirect_array&lt;T&gt;&amp;);
</pre>
<blockquote>
<p><ins>
<i>Requires</i>: The length of the  array to which the argument refers
equals <code>size()</code>.
</ins></p>
<p>
These operators allow the results of a generalized subscripting operation to be assigned directly to a <code>valarray</code>.
</p>
</blockquote>
</blockquote>





</body>
</html>
