2

case 1:

std::valarray<int> data = {1,4,0,2,5};
std::valarray<bool> exp_mask = data <= 2;
std::mask_array<int> marr1 = data[mask];
marr1 = 10;

case 2:

std::valarray<int> data = {1,4,0,2,5};
data[data <= 2] = 11; // 7

case 3:

std::valarray<int> data = {1,4,0,2,5};
std::mask_array<int> marr2 = data[data <= 2];
marr2 = 12;

Case 1 and case 2 both work as expected (data is appropriately modified). However, case 3 fails horribly and unreliably (for me it segfaulted). Upon further inspection with gdb, it looks like the internally stored mask points to the buffer of the temporary data <= 2 valarray, which gets destroyed after line 2. Then when line 3 goes to do the write the mask is complete garbage, and trying to index into it to set the masked values of data is undefined behavior.

I can't find anywhere in the standard why this behavior is allowed (the standard is strangely vague about valarray). Is this libstdc++'s faux pas, or should I expect this result and why?

Compiler settings tested:

  • g++4.8.2 -O0 -g -std=c++0x
  • clang++ -O0 -g -std=c++11

I believe my version of libstdc++ is 3.4.19 (just followed this to find it)

Community
  • 1
  • 1
helloworld922
  • 10,801
  • 5
  • 48
  • 85

0 Answers0