Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does valarray assignment not resize assignee per the documentation?

Code:

#include <valarray>
#include <iostream>    

using namespace std;

int main()
{
  valarray<int> v0(2, 4);
  valarray<int> v1;
  v1 = v0;
  cout << "v0.size: " << v0.size() << endl;
  cout << "v1.size: " << v1.size() << endl;
  cout << "v0[0]: " << v0[0] << endl;
  cout << "v1[0]: " << v1[0] << endl;
}

Output:

v0.size: 4
v1.size: 0
v0[0]: 2
Segmentation fault

For the assignment:

v1 = v0;

I would think the constructor:

valarray<T>& operator=( const valarray<T>& other );

should be used and according to the documentation, I believe v1 should be resized and the contents of v0 copied into it, element for element. So what's actually happening?

$ g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11)
like image 637
Bryant Avatar asked Aug 06 '15 22:08

Bryant


1 Answers

Because you're using old C++.

As of C++11, the destination is resized to match the source.
That's why some contributors here could not reproduce your issue (plus, UB has unpredictable results). It's also why the cppreference.com article states that a resize is first performed (though a disclaimer that this applies only since C++11 might have been nice). [This has now been fixed.]

[C++11: 23.6.2.3] valarray assignment [valarray.assign]

valarray<T>& operator=(const valarray<T>& v);

1   Each element of the *this array is assigned the value of the corresponding element of the argument array. If the length of v is not equal to the length of *this, resizes *this to make the two arrays the same length, as if by calling resize(v.size()), before performing the assignment.

2   Postcondition: size() == v.size().

However, in C++03, your code had undefined behaviour.
That's why you're getting a segmentation fault with your older toolchain. It's also why, when this issue was raised as a GCC bug back in 2003, it was rejected as invalid because the implementation was actually conformant at that time.

[C++03: 23.3.2.2] valarray assignment [valarray.assign]

valarray<T>& operator=(const valarray<T>& v);

1   Each element of the *this array is assigned the value of the corresponding element of the argument array. The resulting behavior is undefined if the length of the argument array is not equal to the length of the *this array.

like image 83
Lightness Races in Orbit Avatar answered Sep 29 '22 21:09

Lightness Races in Orbit