Title
basic_stringbuf default constructor forbids it from using SSO capacity
Status
c++20
Section
[stringbuf.cons]
Submitter
Jonathan Wakely

Created on 2017-07-07.00:00:00 last changed 45 months ago

Messages

Date: 2018-11-12.04:39:29

Proposed resolution:

This wording is relative to N4659.

  1. Edit [stringbuf.cons] as indicated:

    explicit basic_stringbuf(
      ios_base::openmode which = ios_base::in | ios_base::out);
    

    -1- Effects: Constructs an object of class basic_stringbuf, initializing the base class with basic_streambuf() ([streambuf.cons]), and initializing mode with which. It is implementation-defined whether the sequence pointers (eback(), gptr(), egptr(), pbase(), pptr(), epptr()) are initialized to null pointers.

    -2- Postconditions: str() == "".

Date: 2018-11-12.04:39:29

[ 2018-11, Adopted in San Diego ]

Date: 2018-06-12.02:06:47

[ 2018-06 Rapperswil Wednesday issues processing ]

Status to Ready

Date: 2017-07-12.01:58:24

[ 2017-07 Toronto Tuesday PM issue prioritization ]

Priority 3; is this affected by Peter Sommerlad's paper P0407R1?

Date: 2017-07-07.00:00:00

[stringbuf.cons] says that the default constructor initializes the base class as basic_streambuf() which means the all the pointers to the input and output sequences (pbase, eback etc) are all required to be null.

This means that a stringbuf that is implemented in terms of a Small String Optimised std::basic_string cannot make us of the string's initial capacity, and so cannot avoid a call to the overflow virtual function even for small writes. In other words, the following assertions must pass:

#include <sstream>
#include <cassert>

bool overflowed = false;

struct SB : std::stringbuf
{
  int overflow(int c) {
    assert( pbase() == nullptr );
    overflowed = true;
    return std::stringbuf::overflow(c);
  }
};

int main()
{
  SB sb;
  sb.sputc('1');
  assert(overflowed);
}

This is an unnecessary pessimisation. Implementations should be allowed to use the SSO buffer immediately and write to it without calling overflow. Libc++ already does this, so is non-conforming.

History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2018-11-12 04:39:29adminsetmessages: + msg10184
2018-11-12 04:39:29adminsetstatus: voting -> wp
2018-10-08 05:13:59adminsetstatus: ready -> voting
2018-06-12 02:06:47adminsetmessages: + msg9904
2018-06-12 02:06:47adminsetstatus: new -> ready
2017-07-12 01:58:24adminsetmessages: + msg9358
2017-07-08 09:55:24adminsetmessages: + msg9322
2017-07-07 00:00:00admincreate