https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102307

--- Comment #7 from jyhgekyfbkjsyebf at protonmail dot ch ---
Note that:

* based on repro: if I add constexpr to the first ctor and provide body, it
will compile without error. Like this:

constexpr Matrix(double const (&arr)[N][M]) {}

* based on repro: if I comment out the second ctor declaration, compiler will
produce an error (instead of a crash). Like this:

// constexpr Matrix(std::array<std::array<double, M>, N> const &arr);

* based on repro: if I add a data member, and
   * provide body to the first ctor, and
       * inside use std::copy to fill the member

the compiler will crash. Like this:

```
#include <algorithm>
#include <array>
template <unsigned N, unsigned M> struct Matrix {
  std::array<double, N * M> mat;
  Matrix(double const (&arr)[N][M]) {
    std::copy(&arr[0][0], &arr[0][0] + N * M, std::begin(mat));
  }
  constexpr Matrix(std::array<std::array<double, M>, N> const &arr);
};
int main() { constexpr Matrix<2, 3> mat{{{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}}}; }
```

* based on last case: if I replace std::copy call with 2 for loops, and
    * add constexpr to first ctor, and
    * add -std=c++20 flag

the code will compile. Like this:

```
  constexpr Matrix(double const (&arr)[N][M]) {
    for (auto n{0U}; n < N; ++n) {
      for (auto m{0U}; m < M; ++m)
        mat[n * M + m] = arr[n][m];
    }
  }
```

As you can see, the results due to slight changes are all over the place. I
leave it up to you to interpret them. All of the above is reproducible on
godbolt. I only used local gcc to generate backtrace, everything else was
tinkered with there.

Reply via email to