Using gcc 4.9
I found that types generated with type literal for complex numbers are not the same as when created by conventional means, i.e.:
typeid(complex<double>(0.0,1.0)) != typeid(1.0i)
Adding the missing MCVE
#include <complex>
using std::complex;
using namespace std::literals::complex_literals;
#include <iostream>
using std::cout;
using std::endl;
#include <typeinfo>
int main(int argc, char* argv[]) {
if (typeid(complex<double>(0.0, 1.0)) == typeid(1.0i))
cout << "types are same as expected" << endl;
else
cout << "types are unexpectedly not the same" << endl;
cout << 1.0i*1.0i << endl;
cout << complex<double>(0.0, 1.0)*complex<double>(0.0, 1.0) << endl;
}
Compile instructions:
g++ -std=gnu++14 complex.cpp -o complex.exe
Output:
types are unexpectedly not the same
1
(-1,0)
Interestingly the literal does not even seem to be a proper imaginary number. (I am sure I am overlooking something...)
The behaviour of the program depends on the language standard mode of gcc:
There is a gcc extension for a built-in literal suffix i
that produces C99 complex numbers. Those are distinct built-in types like _Complex double
, as opposed to the "user-defined" class (template specialization) std::complex<double>
used in C++.
In C++14, C++ now has a user-defined literal suffix i
for complex numbers. That is, a function complex<double> operator"" i(long double)
within the std::literals::complex_literals
inline namespace.
Those two literal suffixes are competing:
In C++11 mode, only the built-in extension is possible, but it is an extension. Hence, gcc only allows it in -std=gnu++11
mode and even warns you about it. Strangely enough, clang allows it even in -std=c++11
mode.
In strict C++14 mode (-std=c++14
or -std=c++1y
), the built-in extension must be disabled to remove ambiguity (as far as I can tell), hence both gcc and clang selecting the user-defined literal suffix.
In the gnu-extension-C++14 mode -std=gnu++14
, gcc chooses the built-in suffix (for backwards-compatibility?), whereas clang chooses the user-defined suffix. This looks strange, and I'd suggest looking for or filing bug reports here.
Depending on which literal suffix is chosen, you either get the built-in type _Complex double
or some std::complex<double>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With