https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125954
Bug ID: 125954
Summary: operator/ does not match std::complex operands within
C++ modules code
Product: gcc
Version: 15.3.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: sebj_coder3 at pm dot me
Target Milestone: ---
Hi GCC devs,
This issue occurs in a program that carries out a principle components analysis
on some data. The error occurs when I compile my program with GCC 15.3.1. GCC
16 is fine, as are most versions of Clang.
The compiler reports that it cannot divide two std::complex numbers.
I did try to make a minimal example, but I did not succeed, so instead, here
are steps to reproduce the error by compiling my original program:
# Recursively clone sebsjames/maths:
git clone --recurse-submodules [email protected]:sebsjames/maths
# Checkout the bug branch
cd maths
git checkout bugrep/gcc15_complex_arithmetic
# Prepare the build
mkdir build
cd build
CXX=/opt/gcc-16/bin/g++ cmake .. -GNinja
# Compile the problem example, pca_iris:
ninja pca_iris
If successful, you could run:
./tests/pca_iris
and see some program output about the principle components of the data.
The compiler output seen is:
[15:32:12 bgcc15] ninja pca_iris
[29/30] Building CXX object tests/CMakeFiles/pca_iris.dir/pca_iris.cpp.o
FAILED: tests/CMakeFiles/pca_iris.dir/pca_iris.cpp.o
/opt/gcc15/bin/g++ -I/home/seb/src/maths -I/home/seb/src/maths/json/include
-static-libstdc++ -g -Wall -Wextra -Wpedantic -pedantic-errors -Werror
-Wfatal-errors -Wno-psabi -Wno-unknown-pragmas -O3
-fconstexpr-ops-limit=5000000000 -std=gnu++23 -MD -MT
tests/CMakeFiles/pca_iris.dir/pca_iris.cpp.o -MF
tests/CMakeFiles/pca_iris.dir/pca_iris.cpp.o.d -fmodules-ts
-fmodule-mapper=tests/CMakeFiles/pca_iris.dir/pca_iris.cpp.o.modmap -MD
-fdeps-format=p1689r5 -x c++ -o tests/CMakeFiles/pca_iris.dir/pca_iris.cpp.o -c
/home/seb/src/maths/tests/pca_iris.cpp
In module sm.mat, imported at /home/seb/src/maths/sm/pca.cppm:19,
of module sm.pca, imported at /home/seb/src/maths/tests/pca_iris.cpp:12:
/home/seb/src/maths/sm/mat.cppm: In instantiation of ‘void sm::[email protected]<F,
Nr, Nc>::row_echelon_form_inplace() [with Fy = std::complex<double>; F =
std::complex<double>; unsigned int Nr = 4; unsigned int Nc = 5]’:
/home/seb/src/maths/sm/mat.cppm:1097:41: required from
‘sm::[email protected]<std::complex<_Tp>, Nr> sm::[email protected]<F, Nr,
Nc>::eigenvector(const std::complex<_Tp>&) const [with Fy = double; F = double;
unsigned int Nr = 4; unsigned int Nc = 4]’
1097 | aug.row_echelon_form_inplace();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/home/seb/src/maths/sm/mat.cppm:1144:58: required from
‘sm::[email protected]<sm::[email protected]<F, Nr, Nc>::eigenpair, Nr> sm::[email protected]<F,
Nr,
Nc>::eigenpairs() const [with F = double; unsigned int Nr = 4; unsigned int Nc
= 4]’
1144 | pairs[i].eigenvector = this->eigenvector (lambdas[i]);
| ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
/home/seb/src/maths/sm/pca.cppm:70:78: required from
‘sm::pca::[email protected]<T, N> sm::pca::[email protected](const
sm::[email protected]<sm::[email protected]<S>, N>&) [with T = double; unsigned int N = 4]’
70 | sm::vec<typename sm::mat<T, N>::eigenpair, N> pairs =
cm_z.eigenpairs();
|
~~~~~~~~~~~~~~~^~
/home/seb/src/maths/sm/pca.cppm:111:35: required from
‘sm::pca::[email protected]<T, N> sm::pca::[email protected](const
sm::[email protected]<sm::[email protected]<F, Nr> >&) [with T = double; unsigned int N =
4]’
111 | return pca::compute<T, N> (x);
| ~~~~~~~~~~~~~~~~~~~^~~
/home/seb/src/maths/tests/pca_iris.cpp:22:70: required from here
22 | sm::pca::result<double, 4> pca_res = sm::pca::compute<double, 4>
(x);
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
/home/seb/src/maths/sm/mat.cppm:974:45: error: no match for ‘operator/’
(operand types are ‘std::complex<double>’ and ‘std::complex<double>’)
974 | F f = (*this)(i, c) / (*this)(r, c);
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
compilation terminated due to -Wfatal-errors.
ninja: build stopped: subcommand failed.
Line 974 is
F f = (*this)(i, c) / (*this)(r, c);
This is part of a matrix class. Here, F would typically be float, double,
std::complex<float> or std::complex<double>. In this program, it is
std::complex<double>. (*this)(i, c) obtains the element at row i, col c from
the matrix for which this code is a method.
If I workaround this line by writing instead:
F f = (*this)(i, c);
f /= (*this)(r, c);
Then the line compiles, but the compiler moves on to a similar error about
another operation on std::complex. After making about 4 or 5 workarounds, the
errors spilled over into another of my modules (vec.cppm) and I decided that a
bug report might be required!
Many thanks for reading,
Seb James