Doc. No.: WG21/N0857=X3J16/96-0039
Date: 30 Jan 1996
Project: C++ Standard Library
Reply to: David Vandevoorde
vandevod@cs.rpi.edu
Assignment of valarrays
Description
The specifications of the valarray template (as currently included in
the working paper) mandate non-conforming assignments to valarrays to
cause the left-hand side to be resized; i.e., if a is a valarray of
size 10 and b is a valarray of size 20, the expression
a = 2*b;
is required to change the size of a to 20.
Note that although:
valarray a;
a += 2;
is allowed (adding two to every element of a), the following:
a = 2;
is not.
Finally, consider valarrays a and b of size N, and a valarray of
integers P of the same size:
a = b[P];
is a straightforward permutation, but
a = a[P];
may correspond to a much more complex ``in-place'' permutation, which
requires some temporary storage to do correctly. It was unclear to me
if this is the intended behavior or if the result is undefined.
Discussion
The first issue (allowing non-conforming assignments) leads to:
1) loss of performance (only significant for very simple operations
on small arrays or for architectures with very few registers),
2) a subtle difference between `a = a+b;' and `a += b;' (the former
invalidates references to a, whereas the latter does not),
3) hard to find bugs.
The second issue (not allowing `a = 2;' ) is minor, but nevertheless
likely to lead to considerable frustration both in teaching and usage.
The third issue illustrated the more general issue of ``indirect access
order'': does the DWP make guarantees as to the order in which elements
of arrays are assigned. I believe it makes sense not to make such
guarantees,
1) to avoid having to deal with the possibility of unexpected
difficulties in the ``simultaneous assignment'' semantics
(the semantics that make `a = a[P]' work),
2) to simplify the mapping of indirect access operations on
architectures with specialized scatter/gather hardware.
Proposed Resolution
In [lib.valarray.members] 26.3.1.7, remove the fill member function and
its annotations.
In [lib.valarray.access] 26.3.1.3/6, include regular assignments in the
set of operations that do not invalidate references in a valarray.
Replace 26.3.1.2 by text along the lines of:
1 Assignment to an array does not invalidate references into that array.
template valarray& operator=(valarray const&);
2 When invoked, this assignment operator causes each element of the
*this array to be assigned the value of the corresponding element of
the argument array. The behavior is undefined if these two arrays
have different length.
3 Let $L denote the expression evaluating as *this and $R denote the
expression evaluating as the argument of the operator (i.e., the
right hand side). Let further P be an array whose elements are a
permutation of the sequence [0, ..., this->size()-1].
If the effect of:
for (size_t i = 0; i<$L.size(); i++)
$L[P[i]] = $R[i];
depends on the particular permutation that determines P, the
result of the expression is undefined.
template valarray& operator=(T const&);
4 When invoked, this assignment operator causes each element of the
*this array to be assigned the value of the argument.
5 Let $L denote the expression evaluating as *this and $R denote the
expression evaluating as the argument of the operator (i.e., the
right hand side). Let further P be an array whose elements are a
permutation of the sequence [0, ..., this->size()-1].
If the effect of:
for (size_t i = 0; i<$L.size(); i++)
$L[P[i]] = $R;
depends on the particular permutation that determines P, the
result of the expression is undefined.
Note that little would change if the concept of a storage model were
introduced (see another proposed resolution).