11

I have this piece of code summing std::valarray<int>'s:

#include <iostream>
#include <valarray>
#include <vector>

int main()
{
    std::vector<std::valarray<int>> vectorOfValarrays{{1, 1}, {2, 2}, {3, 3}};
    std::valarray<int> sumOfValarrays(2);
    for (const auto& i : vectorOfValarrays)
      sumOfValarrays = sumOfValarrays + i;

    std::cout << sumOfValarrays[0] << ' ' << sumOfValarrays[1];
}

Compiling with x86-64 gcc 12.2 using -O0 and -O1, it prints the expect result:

6 6

But when compiling with -O2 and -O3, it prints:

3 3

What could be the reason for this? Is my code undefined behaviour or is this a gcc bug?

  • 2
    Add `-fno-tree-vectorize` and you get `3 6`. IMO it's a gcc bug. – 273K Jan 28 '23 at 03:33
  • Fwiw: clang and icx both say `6` no matter the optimization level. I think @273K is on to something. – Ted Lyngmo Jan 28 '23 at 04:11
  • 1
    According to [this](https://en.cppreference.com/w/cpp/numeric/valarray/valarray) valarray constructor (2) value-initializes its elements so if it's UB, it's not obvious why. – Nathan Pierson Jan 28 '23 at 04:16
  • Sounds like a [weird](https://godbolt.org/z/WEMve1G69) bug. – Bob__ Jan 28 '23 at 09:50
  • 1
    Hi, does it's related to https://stackoverflow.com/questions/52861540/is-the-glibcxx-stl-incorrect-in-its-implementation-of-stdvalarraysum?rq=1 ? – loic.lopez Jan 28 '23 at 10:41

1 Answers1

3

I'm pretty sure that this is a gcc bug. Clang gives the correct behaviour for all optimization levels (-O0, -O1, -02, -O3). I also have a look at std::valarray constructors, operator + and operator = and it seems like my code doesn't any undefined behaviour.

I found this bug report on gcc Bugzilla, and the problem seems like gcc has the wrong implementation for copying std::valarray, so in the question the line sumOfValarrays = sumOfValarrays + i; makes gcc tripped up.