Home Dashboard Directory Help
Search

VC++ 8 & 9: <sstream> - basic_streambuf::sputc(), sputn() don't increment _Gcount by skitheo1


Status: 

Closed
 as By Design Help for as By Design


1
0
Sign in
to vote
Type: Bug
ID: 509337
Opened: 11/9/2009 11:09:03 AM
Access Restriction: Public
0
Workaround(s)
view
0
User(s) can reproduce this bug

Description

Am I using basic_streambuf::sputc() and basic_streambuf::sputn() wrong (for that matter xsputn()) or is there a bug in them?

Problem:
When I put characters in the streambuf using sputc(), the size reported by basic_streambuf::in_avail() only increases when basic_streambuf::overflow() is called. I.e., basic_streambuf::_Gcount is not incremented with each call to sputc().

Details
Sign in to post a comment.
Posted by Microsoft on 11/20/2009 at 1:51 PM
> Could you point me to where the standard says that it's not required to constantly be correct?

Paragraph 27.5.2.2.3 [lib.streambuf.pub.get]/1 of the 2003 C++ Standard requires that std::basic_streambuf<charT, traits>::in_avail() "Returns: If a read position is available, returns egptr() - gptr(). Otherwise returns showmanyc() (27.5.2.4.3)."

A read position is available, so the question becomes what egptr() and gptr() are required to do. 27.5.2.3.1 [lib.streambuf.get.area]/3 requires that egptr() "Returns: The end pointer for the input sequence." while /2 requires that gptr() "Returns: The next pointer for the input sequence." Therefore, in_avail() will increase when egptr() is advanced.

The other references to egptr() in the Standard are in setg() (which explicitly sets it), underflow() (not relevant here), and overflow() (27.7.1.3 [lib.stringbuf.virtuals]/8 requires "If (mode & ios_base::in) != 0, the function alters the read end pointer egptr() to point just past the new write position", which is exactly what we do).

As for setg(), nothing else in the Standard refers to it.

Therefore, the explanation above was correct.

Stephan T. Lavavej
Visual C++ Libraries Developer
Posted by skitheo1 on 11/19/2009 at 11:49 AM
Thank you for the response.

Please Reconcile with the following:
http://msdn.microsoft.com/en-us/library/658z85h8%28VS.80%29.aspx

Return Value
The number of elements that are ready to be read from the buffer.

Remarks
If a read position is available, the member function returns egptr – gptr. Otherwise, it returns showmanyc.
-----------

http://www.dinkumware.com/manuals/?manual=compleat&page=streambu.html

streamsize in_avail();
If a read position is available, the member function returns egptr() - gptr(). Otherwise, it returns showmanyc().

char_type *egptr() const;
The member function returns a pointer just past the end of the input buffer.

char_type *gptr() const;
The member function returns a pointer to the next element of the input buffer.

---------
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf

27.5.2.2.3 Get area [lib.streambuf.pub.get]
streamsize in_avail ();
1 Returns: If a read position is available, returns egptr() - gptr(). Otherwise returns showmanyc() (27.5.2.4.3).

---------
http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n3000.pdf

27.6.2.2.3 Get area [streambuf.pub.get]
streamsize in_avail();
1 Returns: If a read position is available, returns egptr() - gptr(). Otherwise returns showmanyc() (27.6.2.4.3).

----------
The explanation from Plauger provided no new information, other than asserting that it is conforming. What would be more useful is to point to the portions (sentence or paragraph) of the standard that support that assertion, including by omission.

Could you point me to where the standard says that it's not required to constantly be correct?

If it's not useful, why does it exist????
Posted by Microsoft on 11/18/2009 at 6:51 PM
Hi,

Thanks for reporting this issue. I've resolved it as By Design because this behavior conforms to the C++ Standard. I checked with our iostreams expert, P.J. Plauger of Dinkumware (the company that Microsoft's C++ Standard Library implementation is licensed from), and he explained:

"Basically, we provide a very conservative implementation of in_avail. For basic_stringbuf, we allocate a 32-element buffer the first time you try to write to it. At that time, we set up a one-character overlaid read buffer. in_avail thus reports that (at least) one element can now be read without blocking, which is a conforming answer even if there are more elements available. On writing the 33rd element, we grow the buffer and once again set the end of the read buffer one element into the new extension of the write buffer. Thus the 33, which is a minimum guarantee for in_avail at this point, and hence is also conforming."

Because the Standard doesn't require in_avail to be updated continuously, it's not especially useful.

If you have any further questions, feel free to E-mail me at stl@microsoft.com .

Stephan T. Lavavej
Visual C++ Libraries Developer
Posted by Microsoft on 11/13/2009 at 3:49 AM
Thanks for your feedback.

We were able to reproduce the issue you are seeing. We are routing this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Microsoft on 11/10/2009 at 1:33 AM
Thank you for your feedback, We are currently reviewing the issue you have submitted.
Sign in to post a workaround.