Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Won't Fix
-
4.2.1, 4.2.x, 4.3.x, 5.0.0
-
Solaris 10 and 11
Red Hat Linux, OpenSuSE Linux
Sun C++ Compilers 12.1, 12.2, 12.3Defect is independent of platform and/or compiler
-
Regression, Unit Test Broken
-
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:
#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:
#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.