When compiling with -std=c++0x (and only then), the ctor of g++ drops the sign of zero. (This sometimes devastates the correct choice of branch cuts in the complex plain.) Interestingly, it doesn't happen with my mock complex class. #include <iostream> #include <complex> using namespace std; template<typename _Tp> struct mock_complex { typedef _Tp value_type; _GLIBCXX_CONSTEXPR mock_complex(const _Tp& __r = _Tp(), const _Tp& __i = _Tp()) : _M_real(__r), _M_imag(__i) { } const _Tp real() const { return _M_real; } const _Tp imag() const { return _M_imag; } private: _Tp _M_real; _Tp _M_imag; }; int main() { mock_complex<double> z1(-0.0, 1.0); cout << signbit(z1.real()) << signbit(z1.imag()) << endl; // correct: 10 complex<double> z2(-0.0, 1.0); cout << signbit(z2.real()) << signbit(z2.imag()) << endl; // wrong: 00 }
Confirmed. Looks like a frontend issue (probably related to constexpr?). In .initial we have { struct mock_complex z1 = {._M_real=-0.0, ._M_imag=1.0e+0}; struct complex z2 = {._M_value=__complex__ (0.0, 1.0e+0)}; <<cleanup_point struct mock_complex z1 = {._M_real=-0.0, ._M_imag=1.0e+0};>>; thus z2 is already initialized from a bogus value. Without -std=c++0x we have struct complex z2; <<cleanup_point <<< Unknown tree: expr_stmt std::complex<double>::complex (&z2, -0.0, 1.0e+0) >>>>>; which is correct.
This just PR48760 in a different form, mainline is fine. *** This bug has been marked as a duplicate of bug 48760 ***