This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

3658. basic_streambuf::sputn is both overspecified and underspecified

Section: [] Status: New Submitter: Jonathan Wakely Opened: 2022-01-17 Last modified: 2022-01-23

Priority: 3

View all issues with New status.


The specification for basic_streambuf::sputn is:

Returns: xsputn(s, n).

One interpretation of this implies that sputn can't insert characters directly into the put area if there is space for them, it has to make a virtual call. That has significant overhead for repeated calls, such as inserting many small strings/string_views in a loop.

But another interpretation is that it doesn't use "Effects: Equivalent to" or anything like that, so doesn't say an actual call to xsputn happens. Strictly speaking, it only says it returns the value that xsputn would return, and doesn't even have to produce any of its effects!

We should describe the effects, not the return value, and we should do so in a way that does not overconstrain the implementation. It should not be necessary to make a virtual call to xsputn if the put area has capacity for the characters. On the other hand, if it doesn't have capacity, then calling xsputn is the best option; it allows the derived streambuf to decide how best to handle large writes.

The proposed resolution replaces the Returns: element with an Effects: element, so that we specify that those effects actually occur. A normative remark is added to give the implementation leeway to avoid the virtual call when it isn't needed.

[2022-01-30; Reflector poll]

Set priority to 3 after reflector poll. Jonathan to revise P/R to also cover sgetn.

Proposed resolution:

This wording is relative to N4901.

  1. Modify [] as indicated:

    streamsize sputn(const char_type* s, streamsize n);

    -?- Preconditions: [s, s+n) is a valid range.

    -?- Effects: return xsputn(s, n).

    -?- Remarks: When (epptr() - pptr()) >= n, it is unspecified whether the characters are written directly to the output sequence without calling xsputn.

    -2- Returns: xsputn(s, n).