From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 414 invoked by alias); 14 Apr 2003 17:03:43 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 393 invoked by uid 48); 14 Apr 2003 17:03:42 -0000 Date: Mon, 14 Apr 2003 17:03:00 -0000 Message-ID: <20030414170342.392.qmail@sources.redhat.com> To: gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, paolo@gcc.gnu.org, peturr02@ru.is From: bkoz@gcc.gnu.org Reply-To: bkoz@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, paolo@gcc.gnu.org, peturr02@ru.is, gcc-gnats@gcc.gnu.org Subject: Re: libstdc++/9423: filebuf::pubsetbuf(0, 0) doesn't turn off buffering if called after open X-SW-Source: 2003-04/txt/msg00628.txt.bz2 List-Id: Synopsis: filebuf::pubsetbuf(0, 0) doesn't turn off buffering if called after open State-Changed-From-To: analyzed->feedback State-Changed-By: bkoz State-Changed-When: Mon Apr 14 17:03:41 2003 State-Changed-Why: This is not a bug. In 27.8.1.3 - Member functions [lib.filebuf.members], p 10 basic_streambuf* setbuf(char_type* s, int n); -10- Effects: If setbuf(0,0) is called on a stream before any I/O has occured on that stream, the stream becomes unbuffered. Otherwise the results are implementation-defined. "Unbuffered" means that pbase() and pptr() always return null and output to the file should appear as soon as possible. Note the use of "any" before I/O. Open certainly counts in this regard. Although the standard is not as explicitly detailed as perhaps desired, gcc-2.95, icc-7.x, gcc-3.x seem to all agree on the current behavior. I also think it makes the most sense. I believe the documentation, as you pointed out, is wrong. The following change should be made: std::ofstream os ("/foo/bar/baz"); std::ifstream is ("/qux/quux/quuux"); to std::ofstream os; std::ifstream is; Also, I believe the Paolo, in proposing a change for this, has found some cleanups that still apply. basic_filebuf<_CharT, _Traits>:: setbuf(char_type* __s, streamsize __n) { - if (!this->is_open() && __s == 0 && __n == 0) - this->_M_buf_size = 0; + if (__s == 0 && __n == 0) !is_open too + { + this->_M_buf_size = 0; space before comment + // If setbuf(0, 0) is called before the first I/O + // operation, is guaranteed to work, even if is_open() + // is true. In that case, however, we destroy the + // current internal array. + if (this->is_open()) + { + _M_destroy_internal_buffer(); + _M_set_indeterminate(); + } + } all this no longer applies else if (__s && __n) { // This is implementation-defined behavior, and assumes @@ -428,8 +439,6 @@ // Step 2: Use the external array. this->_M_buf = __s; this->_M_buf_size = __n; - // Consistently set the end of buffer pointer. - this->_M_out_end = this->_M_buf + this->_M_buf_size; this is still ok _M_set_indeterminate(); } http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9423