This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: EOF after __copy_streambufs
- To: libstdc++ at gcc dot gnu dot org
- Subject: Re: EOF after __copy_streambufs
- From: Nathan Myers <ncm at nospam dot cantrip dot org>
- Date: Tue, 9 Oct 2001 16:02:04 -0700
- References: <24wv24tpzg.fsf@ll.mit.edu>
- Reply-To: libstdc++ at gcc dot gnu dot org
On Tue, Oct 09, 2001 at 06:20:35PM -0400, Brad Howes wrote:
> Is the EOF after copying streambufs from iss to cout valid (g++ 3.0.1)?
>
> #include <iostream>
> #include <strstream>
>
> int
> main( int argc, const char* argv[] )
> {
> const char* data = "first line # comment\n\
> second line\n\
> # commentary line\n\
> last line\n";
>
> std::istrstream iss( data );
> std::cout << "Original:" << std::endl << iss.rdbuf();
> short state = std::cout.rdstate();
> std::cout.clear();
> std::cout << "flags: " << std::hex << state << std::endl;
> return 0;
> }
>
> When run, I get:
>
> Original:
> first line # comment
> second line
> # commentary line
> last line
> flags: 2
>
> which is indicates that cout's ios::eofbit was set. It gets set by the
> __copy_streambufs template function in streambuf.tcc. When the above
> code is compiled under Sun's Forte v5, the eofbit does not get set.
> Which is correct?
std::cout's eofbit should never be set under any circumstances.
The only standard library operation that should ever set eofbit
is an extractor that fails because it encountered EOF, or that
reads EOF and determines from that that its object is complete.
(Note that in the latter case, it sets eofbit but not failbit,
and the extraction succeeds.)
Looking at the code in streambuf.tcc, it appears that the author
got confused about which stream the __ios argument referred to.
In addition, the caller in istream.tcc got confused about how to
call it. The correct fix is to remove the code from streambuf.tcc
and add it to the call site in istream.tcc. That is,
- __xtrct = __copy_streambufs(*this, __sbin, __sbout);
+ {
+ __xtrct = __copy_streambufs(*this, __sbin, __sbout);
+ this->setstate(ios_base::eofbit);
+ }
Maybe some exception jimmying would be appropriate as well.
Nathan Myers
ncm at cantrip dot org