This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
libstdc++/10101: [3.0/3.2/3.3/3.4 regression] seekp() on std::strstream can break reading back from the stream
- From: andrew at andypo dot net
- To: gcc-gnats at gcc dot gnu dot org
- Date: 15 Mar 2003 16:50:06 -0000
- Subject: libstdc++/10101: [3.0/3.2/3.3/3.4 regression] seekp() on std::strstream can break reading back from the stream
- Reply-to: andrew at andypo dot net
>Number: 10101
>Category: libstdc++
>Synopsis: [3.0/3.2/3.3/3.4 regression] seekp() on std::strstream can break reading back from the stream
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Mar 15 16:56:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Andrew Pollard
>Release: gcc-3_0-branch, gcc-3_2-branch, gcc-3_3-branch, gcc head
>Organization:
>Environment:
RedHat8.0/PIII system
Sun Sparc Solaris2.6/2.8
>Description:
I know that std::strstream is deprecated, but I've come across (what I'm pretty sure is) a bug in it, which would be nice to fix (pseudo patch attached in the 'Fix' section)
The following code:
strstream.cxx:
-------------------------
#include <strstream>
#include <string>
#include <iostream>
int
main()
{
std::strstream s;
s << "Hello" << std::ends;
s.seekp(0, std::ios::beg);
s.seekg(0, std::ios::beg);
std::string str;
s >> str;
std::cout << str << std::endl;
return (0);
}
-----------------------
Doesn't print out "Hello", but prints nothing.
It works if a std::stringstream is used instead.
It also works if the seekp() is removed.
It works with gcc-2.95, MSVC++6.0 and Intel icc-7.0.
Basically, if you seekp() the writing position, when strstreambuf::underflow next is called, and the pptr() is now past egptr(), then egptr() is set to pptr().
This has the effect that if you write into a strstream, and don't read anything from it (egptr() == eback()), when you seekp(0, std::ios::beg), you then cannot read the written data out of the stream, since egptr() == eback(), causing underflow, which doesn't change egptr(), and thus you get
_Traits::eof() returned.
This worked in gcc-2.95 since the implementation was completly different (using libio). Interestingly STLport has the same problem, looks like this might be a "day 1" SGI STL bug...
>How-To-Repeat:
>Fix:
I think it is a simple change to strstreambuf::underflow()
[ libstdc++-v3/src/strstream.cc ]
This is the code from the gcc-3_2-branch:
strstreambuf::int_type
strstreambuf::underflow()
{
if (gptr() == egptr() && pptr() && pptr() > egptr())
setg(eback(), gptr(), pptr());
if (gptr() != egptr())
return (unsigned char) *gptr();
else
return _Traits::eof();
}
[ same for gcc-3.0/3.3/3.4 ]
Changing the pptr()'s to epptr()'s appears to fix the problem, ie
if (gptr() == egptr() && epptr() && epptr() > egptr())
setg(eback(), gptr(), epptr());
ie, if the end of the current writing buffer is past the current end of the reading buffer, set the reading buffer to the current writing buffer.
Looking at the gcc-2.95 sources, and what std::stringstream does, this seems to be an equivalent implementation.
>Release-Note:
>Audit-Trail:
>Unformatted: