Bug 1737 - showpos is bugged in gcc-4.2.1
showpos is bugged in gcc-4.2.1
Status: RESOLVED FIXED
Product: ns-3
Classification: Unclassified
Component: core
pre-release
All All
: P5 normal
Assigned To: Peter Barnes
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2013-07-26 17:37 EDT by Tom Henderson
Modified: 2013-08-01 21:46 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Henderson 2013-07-26 17:37:04 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.
Comment 1 Peter Barnes 2013-07-29 20:23:58 EDT
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
Comment 2 Peter Barnes 2013-08-01 21:46:47 EDT
Commit r10106 41f46a8e5a96