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

                 Key: STDCXX-1059
                 URL: https://issues.apache.org/jira/browse/STDCXX-1059
             Project: C++ Standard Library
          Issue Type: Bug
          Components: 27. Input/Output
    Affects Versions: 4.2.1, 4.2.x, 4.3.x, 5.0.0
         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

            Reporter: Stefan Teleman
             Fix For: 4.2.2, 4.2.x, 4.3.x, 5.0.0


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

{code title=test.cc|borderStyle=solid}
#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;
}
{code}

1. Output from GCC 4.5.0:
{noformat}
[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
{noformat}

2. Output from Sun C++ 12.2 with stlport:
{noformat}
[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
{noformat}

3. Output rom Sun C++ 12.2 with our patched stdcxx:
{noformat}
[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
{noformat}

4. Output from Pathscale 4.0.12.1 (which did not patch stdcxx):
{noformat}
[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
{noformat}

Simplified test case identifying the problem:
{code title=flags.cc|borderStyle=solid}

#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;
}
{code}

1. Output from GCC 4.5.0:
{noformat}
[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
{noformat}

2. Output from Sun C++ 12.2 with stlport:
{noformat}
[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
{noformat}

3. Output from Sun C++ 12.2. with our patched stdcxx:
{noformat}
[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
{noformat}

The defect is in

{noformat}
std::ios_base::setf(fmtflags fl);
and
std::ios_base::unsetf(fmtflags fl);
{noformat}

in the original stdcxx implementation. The member function

{noformat}
fmtflags std::ios_base::flags() const;
{noformat}

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.



--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to