Uploaded image for project: 'C++ Standard Library'
  1. C++ Standard Library
  2. STDCXX-1059

std::ios_base::setf() and std::ios_base::unsetf() do not set/clear the format flags correctly

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Won't Fix
    • Affects Version/s: 4.2.1, 4.2.x, 4.3.x, 5.0.0
    • Fix Version/s: 4.2.2, 4.2.x, 4.3.x, 5.0.0
    • Component/s: 27. Input/Output
    • Environment:

      Solaris 10 and 11
      Red Hat Linux, OpenSuSE Linux
      Sun C++ Compilers 12.1, 12.2, 12.3

      Defect is independent of platform and/or compiler

    • Regression:
      Regression, Unit Test Broken
    • Severity:
      Incorrect Behavior

      Description

      std::ios_base::setf (fmtflags fl) and std::ios_base::unsetf (fmtflags fl)
      do not set or clear the format flags correctly:

      test.cc
      #include <ios>
      #include <iostream>
      #include <fstream>
      
      int main()
      {
          std::fstream strm;
          std::ios_base::fmtflags fl;
          int ret = 0;
      
          fl = std::ios_base::dec;
          strm.unsetf(fl);
      
          fl = std::ios_base::hex;
      
          strm.setf(fl);
          strm.unsetf(fl);
      
          if (strm.flags() & fl)
          {
              std::cerr << "failure to clear hex flags" << std::endl;
              ++ret;
          }
      
          return ret;
      }
      

      1. Output from GCC 4.5.0:

      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:19:37][1957]>> ./test-gcc 
      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:20:02][1958]>> echo $status
      0
      

      2. Output from Sun C++ 12.2 with stlport:

      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:20:24][1959]>> ./test-ss122-stlport 
      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:08][1960]>> echo $status
      0
      

      3. Output rom Sun C++ 12.2 with our patched stdcxx:

      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:09][1961]>> ./test-ss122-stdcxx 
      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:44][1962]>> echo $status
      0
      

      4. Output from Pathscale 4.0.12.1 (which did not patch stdcxx):

      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:46][1963]>> ./test-pathscale 
      failure to clear hex flags
      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:22:48][1964]>> echo $status
      1
      

      Simplified test case identifying the problem:

      flags.cc
      #include <iostream>
      #include <ios>
      
      class BadTest
      {
      public:
          BadTest() : _flags(0) { }
          ~BadTest() { }
      
          unsigned int flags() const { return _flags; }
          unsigned int flags (unsigned int f)
          {
              unsigned int ret = _flags;
              _flags |= f;
              return ret;
          }
          unsigned int setf (unsigned int f) { return flags (flags() | f); }
          void unsetf (unsigned int f) { flags (flags() & ~f); }
      
      private:
          unsigned int _flags;
      };
      
      class GoodTest
      {
      public:
          GoodTest() : _flags(0) { }
          ~GoodTest() { }
      
          unsigned int flags() const { return _flags; }
          unsigned int flags (unsigned int f)
          {
              unsigned int ret = _flags;
              _flags |= f;
              return ret;
          }
          unsigned int setf (unsigned int f)
          {
              unsigned int ret = _flags;
              _flags |= f;
              return ret;
          }
          void unsetf (unsigned int f) { _flags &= ~f; }
      
      private:
          unsigned int _flags;
      };
      
      int main()
      {
          BadTest bt;
          std::ios_base::fmtflags fl;
      
          std::cerr << "***** BadTest *****" << std::endl;
          std::cerr << "default flags: " << bt.flags() << std::endl;
      
          fl = std::ios_base::dec;
      
          bt.setf(fl);
          std::cerr << "flags: " << bt.flags() << std::endl;
      
          bt.unsetf(fl);
          std::cerr << "flags: " << bt.flags() << std::endl;
      
          fl = std::ios_base::hex;
      
          bt.setf(fl);
          std::cerr << "flags: " << bt.flags() << std::endl;
      
          bt.unsetf(fl);
          std::cerr << "flags: " << bt.flags() << std::endl;
      
          std::cerr << std::endl;
      
          GoodTest gt;
          std::cerr << "***** GoodTest *****" << std::endl;
          std::cerr << "default flags: " << gt.flags() << std::endl;
      
          fl = std::ios_base::dec;
      
          gt.setf(fl);
          std::cerr << "flags: " << gt.flags() << std::endl;
      
          gt.unsetf(fl);
          std::cerr << "flags: " << gt.flags() << std::endl;
      
          fl = std::ios_base::hex;
      
          gt.setf(fl);
          std::cerr << "flags: " << gt.flags() << std::endl;
      
          gt.unsetf(fl);
          std::cerr << "flags: " << gt.flags() << std::endl;
      
          return 0;
      }
      

      1. Output from GCC 4.5.0:

      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:01][1968]>> ./flags-gcc 
      ***** BadTest *****
      default flags: 0
      flags: 2
      flags: 2
      flags: 10
      flags: 10
      
      ***** GoodTest *****
      default flags: 0
      flags: 2
      flags: 0
      flags: 8
      flags: 0
      

      2. Output from Sun C++ 12.2 with stlport:

      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:05][1969]>> ./flags-ss122-stlport 
      ***** BadTest *****
      default flags: 0
      flags: 8
      flags: 8
      flags: 24
      flags: 24
      
      ***** GoodTest *****
      default flags: 0
      flags: 8
      flags: 0
      flags: 16
      flags: 0
      

      3. Output from Sun C++ 12.2. with our patched stdcxx:

      [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:12][1970]>> ./flags-ss122-stdcxx 
      ***** BadTest *****
      default flags: 0
      flags: 2
      flags: 2
      flags: 10
      flags: 10
      
      ***** GoodTest *****
      default flags: 0
      flags: 2
      flags: 0
      flags: 8
      flags: 0
      

      The defect is in

      std::ios_base::setf(fmtflags fl);
      and
      std::ios_base::unsetf(fmtflags fl);
      

      in the original stdcxx implementation. The member function

      fmtflags std::ios_base::flags() const;
      

      returns by value. Any bitwise operations on the anon temporary created by
      this function do not affect the __fmtflags data member of std::ios_base,
      which remains unchanged.

      Patch for stdcxx 4.2.1 to follow.

        Attachments

        1. test.cc
          0.4 kB
          Stefan Teleman
        2. flags.cc
          2 kB
          Stefan Teleman

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              steleman Stefan Teleman
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: