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

Section 29.2 <a href="https://wg21.link/numeric.requirements">[numeric.requirements]</a>, p1     suggests     that     a
<code>valarray</code>  specialization on  a  type <code>T</code>  that
satisfies  the requirements enumerated  in the  paragraph is  itself a
valid  type   on  which  <code>valarray</code>   may  be  instantiated
(Footnote       269        makes       this       clear).        I.e.,
<code>valarray&lt;valarray&lt;T&gt;  &gt;</code> is  valid as  long as
<code>T</code>   is   valid.    However,  since   implementations   of
<code>valarray</code> are permitted to initialize storage allocated by
the class by  invoking the default ctor of  <code>T</code> followed by
the    copy    assignment    operator,   such    implementations    of
<code>valarray</code>   wouldn't  work  with   (perhaps  user-defined)
specializations of <code>valarray</code> whose assignment operator had
undefined behavior when the size of its argument didn't match the size
of <code>*this</code>.  By <i>"wouldn't work"</i> I mean that it would
be  impossible  to resize  such  an array  of  arrays  by calling  the
<code>resize()</code> member  function on it if the  function used the
copy  assignment operator  after constructing  all elements  using the
default  ctor (e.g.,  by invoking  <code>new  value_type[N]</code>) to
obtain default-initialized storage) as it's permitted to do.

        </p>
        <p>

Stated      more     generally,      the      problem     is      that
<code>valarray&lt;valarray&lt;T&gt;  &gt;::resize(size_t)</code> isn't
required or  guaranteed to have well-defined semantics  for every type
<code>T</code>     that      satisfies     all     requirements     in
29.2 <a href="https://wg21.link/numeric.requirements">[numeric.requirements]</a>.

        </p>
        <p>

I  believe  this  problem  was  introduced  by  the  adoption  of  the
resolution                outlined                in                <a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1996/N0857.asc">N0857</a>,
<i>Assignment  of  valarrays</i>,  from  1996.   The  copy  assignment
operator  of  the original  numerical  array  classes  proposed in  <a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0280.pdf">N0280</a>,
as      well       as      the      one       proposed      in      <a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0308.asc">N0308</a>
(both  from 1993), had  well-defined semantics  for arrays  of unequal
size (the  latter explicitly  only when <code>*this</code>  was empty;
assignment of non empty arrays of unequal size was a runtime error).

        </p>
        <p>

The  justification for  the  change given  in  N0857 was the "loss  of
performance [deemed]  only significant  for very simple  operations on
small arrays or for architectures with very few registers."

        </p>
        <p>

Since tiny  arrays on a  limited subset of hardware  architectures are
likely  to  be  an   exceedingly  rare  case  (despite  the  continued
popularity of  x86) I  propose to revert  the resolution and  make the
behavior    of   all   <code>valarray</code>    assignment   operators
well-defined even  for non-conformal  arrays (i.e., arrays  of unequal
size).   I have implemented  this change  and measured  no significant
degradation  in performance in  the common  case (non-empty  arrays of
equal size).  I  have measured a 50% (and in  some cases even greater)
speedup  in the  case of  assignments to  empty arrays  versus calling
<code>resize()</code>  first followed  by  an invocation  of the  copy
assignment operator.

        </p>

<p><i>[
Bellevue:
]</i></p>


<blockquote><p>
If no proposed wording by June meeting, this issue should be closed NAD.
</p></blockquote>

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


<blockquote>
<p>
Move resolution 1 to Ready.
</p>
<p>
Howard: second resolution has been commented out (made invisible).
Can be brought back on demand.
</p>
</blockquote>



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

Change 29.6.2.3 <a href="https://wg21.link/valarray.assign">[valarray.assign]</a>, p1 as follows:

        </p>
        <blockquote>
            <p>
                <code>

valarray&lt;T&gt;&amp; operator=(const valarray&lt;T&gt;&amp;<ins> x</ins>);

                </code>
            </p>
            <p>

-1- Each element of the <code>*this</code> array is assigned the value
of  the  corresponding  element   of  the  argument  array.   <del>The
resulting behavior is undefined if </del><ins>When </ins>the length of
the  argument  array  is  not   equal  to  the  length  of  the  *this
array<del>.</del><ins>  resizes  <code>*this</code>  to make  the  two
arrays     the      same     length,     as      if     by     calling
<code>resize(x.size())</code>, before performing the assignment.</ins>

            </p>
        </blockquote>
        <p>

And  add a new  paragraph just  below paragraph  1 with  the following
text:

        </p>
        <blockquote>
            <p>

<ins>-2- <i>Postcondition</i>: <code>size() == x.size()</code>.</ins>

            </p>
        </blockquote>
        <p>

Also add the following paragraph to 29.6.2.3 <a href="https://wg21.link/valarray.assign">[valarray.assign]</a>, immediately after p4:

        </p>
        <blockquote>
            <p>

<ins>-?- When the length,  <i><code>N</code></i> of the array referred
to by the  argument is not equal to  the length of <code>*this</code>,
the  operator resizes <code>*this</code>  to make  the two  arrays the
same  length, as if  by calling  <code>resize(<i>N</i>)</code>, before
performing the assignment.</ins>

            </p>
        </blockquote>

<p><i>[
pre-Sophia Antipolis, Martin adds the following compromise wording, but
prefers the original proposed resolution:
]</i></p>






<p><i>[
Kona (2007): Gaby to propose wording for an alternative resolution in
which you can assign to a <code>valarray</code> of size 0, but not to any other
<code>valarray</code> whose size is unequal to the right hand side of the assignment.
]</i></p>





</body>
</html>
