In my calculations I use the imaginary unit and I think that the compiler should be able to simplify these operations at compile time by reducing things like
a + i b --> std::complex(a,b)
Of course the above is simplified and my expressions usually look more complex (pun intended).
In C++14 I can use the complex literals for that, whereas in C++11 I was using a constexpr std::complex
variable. However, both of these methods fail with the Intel C++ Compiler icpc
with the error messages as comments in the source.
How can I work around these glitches?
#include <complex>
auto test1(double a, double b)
{
// error #1909: complex integral types are not supported
using namespace std::complex_literals;
auto z = a + 1i*b;
return z;
}
auto test2(double a, double b)
{
// error: calling the default constructor for "std::complex<double>" does not produce a constant value
constexpr std::complex<double> I(0,1);
auto z = a + I*b;
return z;
}
auto test3(double a, double b)
{
// Can this be optimized as good as the others?
std::complex<double> I(0,1);
auto z = a + I*b;
return z;
}
Bonus question: Why is test2
optimized away and replaced by a jump to test3
? (see https://godbolt.org/g/pW1JZ8)
The error on complex literals is self-explanatory. The version of the intel compiler I got handy (16.0.3) neither supports them.
When it comes to the second error, I'd say it mostly depends on the GCC standard library version you are using, because icpc does not ship a (complete) standard library. I have installed GCC 5.4 and your test2
function compiles correctly.
What should make the difference is whether the constructor of std::complex
is anotated constexpr
. In GCC 5.4 it is:
_GLIBCXX_CONSTEXPR complex(const _Tp& __r = _Tp(), const _Tp& __i = _Tp()) : _M_real(__r), _M_imag(__i) { }