public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters
@ 2003-03-09 11:27 paolo
  0 siblings, 0 replies; 6+ messages in thread
From: paolo @ 2003-03-09 11:27 UTC (permalink / raw)
  To: gcc-bugs, gcc-prs, paolo, peturr02

Synopsis: i/ostream::operator>>/<<(streambuf*) drops characters

State-Changed-From-To: analyzed->closed
State-Changed-By: paolo
State-Changed-When: Sun Mar  9 11:27:03 2003
State-Changed-Why:
    Fixed for 3.3 and 3.4.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9424


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters
@ 2003-03-07 21:26 Paolo Carlini
  0 siblings, 0 replies; 6+ messages in thread
From: Paolo Carlini @ 2003-03-07 21:26 UTC (permalink / raw)
  To: paolo; +Cc: gcc-prs

The following reply was made to PR libstdc++/9424; it has been noted by GNATS.

From: Paolo Carlini <pcarlini@unitus.it>
To: Nathan Myers <ncm@cantrip.org>
Cc: libstdc++@gcc.gnu.org,  gcc-gnats@gcc.gnu.org
Subject: Re: libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters
Date: Fri, 07 Mar 2003 22:25:52 +0100

 Nathan Myers wrote:
 
 >>int_type c;
 >>while ((c = sbin->sbumpc()) != traits_type::eof() &&
 >>       (sbout->sputc(c) != traits_type::eof())
 >>  {}
 >>
 >I seem to recall that sbumpc() can be implemented more efficiently
 >than snextc, although it's just possible I was smoking crack.
 >
 Hi Nathan. Thanks for your feedback.
 Indeed (*), the basic loop is much more elegant in terms of sbumpc, and more
 efficient too, I guess, since our snextc is implemented in terms of  sbumpc:
 
     int_type
     snextc()
       {
         int_type __eof = traits_type::eof();
         return (traits_type::eq_int_type(this->sbumpc(), __eof)
                 ? __eof : this->sgetc());
       }
 
 However, in the application I want to count separately the number of 
 succesful
 reads (__charsread) and writes (__xtrct) like this:
 
     __xtrct = __charsread = 0;
     int_type __c = __sbin->sgetc();
     while (!_Traits::eq_int_type(__c, _Traits::eof()))
       {
         ++__charsread;
         if (_Traits::eq_int_type(__sbout->sputc(_Traits::to_char_type(__c)),
                                  _Traits::eof()))
           break;
         ++__xtrct;
         ++__ret;
         __c = __sbin->snextc();
       }
 
 and can't see a straightforward way to use your suggestion. Can you?
 
 Otherwise, as indicated by Benjamin, for the time being I would check in
 this correctness fix with the promise of returning to this function to
 streamline it in the _near_ future.
 
 Thanks,
 Paolo.
 
 (*) I want to buy crack from your pusher: seems excellent!
 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters
@ 2003-03-07 19:56 Nathan Myers
  0 siblings, 0 replies; 6+ messages in thread
From: Nathan Myers @ 2003-03-07 19:56 UTC (permalink / raw)
  To: paolo; +Cc: gcc-prs

The following reply was made to PR libstdc++/9424; it has been noted by GNATS.

From: Nathan Myers <ncm@cantrip.org>
To: libstdc++@gcc.gnu.org
Cc: gcc-gnats@gcc.gnu.org
Subject: Re: libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters
Date: Fri, 7 Mar 2003 11:50:55 -0800

 On Wed, Feb 26, 2003 at 09:27:32AM -0000, P?tur Run?lfsson wrote:
 > I believe the relevant quote is in 27.6.2.5.3 p7, bullet 2:
 > 
 >   inserting in the output sequence fails (in which case the
 >   character to be inserted is not extracted);
 > 
 > So correct code is "as if":
 > 
 > int_type c = sbin->sgetc();
 > while (c != traits_type::eof())
 > {
 >   if (sbout->sputc(c) == traits_type::eof())
 >     break;
 >   c = sbin->snextc();
 > }
 > 
 > Of course, it should be OK to call sgetn if the function *knows*
 > that sputc won't fail (for example if epptr() - pptr() is big
 > enough).
 
 I wonder if this wouldn't be better implemented using sbumpc:
 
 > int_type c;
 > while ((c = sbin->sbumpc()) != traits_type::eof() &&
 >        (sbout->sputc(c) != traits_type::eof())
 >   {}
 
 I seem to recall that sbumpc() can be implemented more efficiently
 than snextc, although it's just possible I was smoking crack.
 
 Nathan Myers
 ncm-nospam@cantrip.org


^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters
@ 2003-02-26  9:36 Pétur Runólfsson
  0 siblings, 0 replies; 6+ messages in thread
From: Pétur Runólfsson @ 2003-02-26  9:36 UTC (permalink / raw)
  To: paolo; +Cc: gcc-prs

The following reply was made to PR libstdc++/9424; it has been noted by GNATS.

From: =?iso-8859-1?Q?P=E9tur_Run=F3lfsson?= <peturr02@ru.is>
To: <paolo@gcc.gnu.org>,
	<bkoz@redhat.com>,
	<gcc-bugs@gcc.gnu.org>,
	<ncm@cantrip.org>,
	<nobody@gcc.gnu.org>,
	=?iso-8859-1?Q?P=E9tur_Run=F3lfsson?= <peturr02@ru.is>,
	<gcc-gnats@gcc.gnu.org>
Cc:  
Subject: RE: libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters
Date: Wed, 26 Feb 2003 09:27:32 -0000

 >     The issue is the following: when a setg(buf, buf, buf + 10)
 >     is missing, __copy_streambufs, called by operator>>, ends up
 >     using sgetn to fill an internal temporary buffer.
 >    =20
 >     The latter, in turn, calls unavoidably the custom uflow,
 >     which moves 'current' past the end of the buffer, and=20
 >     underflow, called by sgetc, does not return the expected
 >     '1'.
 >    =20
 >     Now, everything boild down to the following general=20
 >     question: is an implementation of operator>> allowed to
 >     call (indirectly) sgetn?
 
 I believe the relevant quote is in 27.6.2.5.3 p7, bullet 2:
 
   inserting in the output sequence fails (in which case the
   character to be inserted is not extracted);
 
 So correct code is "as if":
 
 int_type c =3D sbin->sgetc();
 while (c !=3D traits_type::eof())
 {
   if (sbout->sputc(c) =3D=3D traits_type::eof())
     break;
   c =3D sbin->snextc();
 }
 
 Of course, it should be OK to call sgetn if the function *knows*
 that sputc won't fail (for example if epptr() - pptr() is big
 enough).
 
 Petur


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters
@ 2003-02-26  0:34 paolo
  0 siblings, 0 replies; 6+ messages in thread
From: paolo @ 2003-02-26  0:34 UTC (permalink / raw)
  To: bkoz, gcc-bugs, gcc-prs, ncm, nobody, paolo, peturr02

Synopsis: i/ostream::operator>>/<<(streambuf*) drops characters

Responsible-Changed-From-To: unassigned->paolo
Responsible-Changed-By: paolo
Responsible-Changed-When: Wed Feb 26 00:34:53 2003
Responsible-Changed-Why:
    Analyzed.
State-Changed-From-To: open->analyzed
State-Changed-By: paolo
State-Changed-When: Wed Feb 26 00:34:53 2003
State-Changed-Why:
    The issue is the following: when a setg(buf, buf, buf + 10)
    is missing, __copy_streambufs, called by operator>>, ends up
    using sgetn to fill an internal temporary buffer.
    
    The latter, in turn, calls unavoidably the custom uflow,
    which moves 'current' past the end of the buffer, and 
    underflow, called by sgetc, does not return the expected
    '1'.
    
    Now, everything boild down to the following general 
    question: is an implementation of operator>> allowed to
    call (indirectly) sgetn?
    
    If so, the PR seems "only" a QoI issue, otherwise, a real 
    bug, which can be fixed in many ways. For example, avoiding
    the call in __copy_streambufs (with a wrapper?)
    
    Nathan? Benjamin?
    
    Paolo.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9424


^ permalink raw reply	[flat|nested] 6+ messages in thread

* libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters
@ 2003-01-23 19:06 peturr02
  0 siblings, 0 replies; 6+ messages in thread
From: peturr02 @ 2003-01-23 19:06 UTC (permalink / raw)
  To: gcc-gnats


>Number:         9424
>Category:       libstdc++
>Synopsis:       i/ostream::operator>>/<<(streambuf*) drops characters
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 23 19:06:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     peturr02@ru.is
>Release:        gcc-3.2.1
>Organization:
>Environment:
Red Hat Linux 8.0
>Description:
basic_istream<>::operator>>(basic_streambuf<>*) and basic_ostream<>::operator<<(basic_streambuf<>*) drop characters on the floor by extracting characters from the source before they have been successfully inserted into the sink.

This seems to happen only if the source is unbuffered, if the source is buffered, extraction happens after insertion as required.
>How-To-Repeat:
See attachment.
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="streambufcopybug2.cc"
Content-Disposition: inline; filename="streambufcopybug2.cc"

#include <streambuf>
#include <istream>
#include <ostream>
#include <cstring>

#undef NDEBUG
#include <cassert>

using namespace std;

class Outbuf : public streambuf
{
	char buf[1];

public:
	Outbuf()
		{
			setp(buf, buf + 1);
		}

	int_type overflow(int_type c)
		{
			int_type eof = traits_type::eof();

			if (pptr() < epptr())
			{
				if (traits_type::eq_int_type(c, eof))
					return traits_type::not_eof(c);

				*pptr() = traits_type::to_char_type(c);
				pbump(1);
				return c;
			}

			return eof;
		}
};

class Inbuf : public streambuf
{
	static const char buf[];
	const char* current;
	int size;

public:
	Inbuf()
		{
			current = buf;
			size = strlen(buf);
		}

	int_type underflow()
		{
			if (current < buf + size)
				return traits_type::to_int_type(*current);
			return traits_type::eof();
		}

	int_type uflow()
		{
			if (current < buf + size)
				return traits_type::to_int_type(*current++);
			return traits_type::eof();
		}
};

const char Inbuf::buf[] = "0123456789";

int main()
{
	Inbuf inbuf1;
	istream is (&inbuf1);
	Outbuf outbuf1;
	is >> &outbuf1;
	assert(inbuf1.sgetc() == '1');

	Outbuf outbuf2;
	ostream os (&outbuf2);
	Inbuf inbuf2;
	os << &inbuf2;
	assert(inbuf2.sgetc() == '1');

	return 0;
}


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-03-09 11:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-03-09 11:27 libstdc++/9424: i/ostream::operator>>/<<(streambuf*) drops characters paolo
  -- strict thread matches above, loose matches on Subject: below --
2003-03-07 21:26 Paolo Carlini
2003-03-07 19:56 Nathan Myers
2003-02-26  9:36 Pétur Runólfsson
2003-02-26  0:34 paolo
2003-01-23 19:06 peturr02

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).