libstdc++/9423: filebuf::pubsetbuf(0, 0) doesn't turn off buffering if called after open

bkoz@gcc.gnu.org bkoz@gcc.gnu.org
Mon Apr 14 17:03:00 GMT 2003


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



More information about the Gcc-bugs mailing list