Bugzilla – Bug 1737
showpos is bugged in gcc-4.2.1
Last modified: 2013-08-01 21:46:47 EDT
Peter cleaned up this operator in changeset 9965:ebc31ec26706 user: Peter D. Barnes, Jr. <barnes26@llnl.gov> date: Wed Jul 24 11:34:04 2013 -0700 summary: Fix output of int64x64_t when value is near min std::ostream &operator << (std::ostream &os, const int64x64_t &value) { int64_t hi = value.GetHigh (); - os << ((hi<0) ? "-" : "+") << ((hi<0) ? -hi : hi) << "."; + os << std::showpos << hi << std::noshowpos << "."; uint64_t low = value.GetLow (); uint8_t msd = MostSignificantDigit (~((uint64_t)0)); do However, showpos is bugged in gcc-4.2.1: http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html This is causing our 'mobility-trace' suite to fail, since it is outputting values at time zero, which are rendered like this on OS X: now=0.0ns node=0 pos=1.000:1.000:0.000 vel=-0.293:-0.956:0.000 instead of the correct: now=+0.0ns node=0 pos=1.000:1.000:0.000 vel=-0.293:-0.956:0.000 Is the cleanest way to handle this to revert? But the hg log suggests that there is some other problem that Peter was fixing.
Given int64_t imin = std::numeric_limits<in64_t>::min(); the original code os << ((hi<0) ? "-" : "+") << ((hi<0) ? -hi : hi) << "."; prints --9223372036854775808.0 Note the two '-' minus signs. This is because - imin == imin, that is, there are two identities for negation, imin and zero, instead of just zero. The r9965 patch replaced the original code with os << std::showpos << hi << "."; (This is almost correct: it neglects to restore the stream format after setting showpos.) I propose the following: // Save stream format flags std::ios_base::fmtflags ff = os.flags (); { // This block should be a simple // os << std::showpos << hi << "."; // but for a bug in libstc++ affecting showpos of zero. // This bug has been around since at least 2004 // (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15565) // but still present in at least some libstc++ 4.2 // (http://gcc.gnu.org/ml/libstdc++/2007-11/msg00074.html) // (http://openbsd.7691.n7.nabble.com/Patch-to-fix-libstdc-std-showpos-td162922.html) if (hi == 0) { os << '+'; // work around libstc++ 4.2 bug } else { os << std::showpos; } os << hi << "."; } os.flags (ff); // Restore stream flags
Commit r10106 41f46a8e5a96