basic_streambuf::sputn
is both overspecified and underspecifiedSection: 31.6.3.3.5 [streambuf.pub.put] Status: New Submitter: Jonathan Wakely Opened: 2022-01-17 Last modified: 2022-01-30
Priority: 3
View all issues with New status.
Discussion:
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.
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.
Modify 31.6.3.3.5 [streambuf.pub.put] as indicated:
streamsize sputn(const char_type* s, streamsize n);-?- Preconditions:
-?- Effects:[s, s+n)
is a valid range.return xsputn(s, n)
. -?- Remarks: When(epptr() - pptr()) >= n
, it is unspecified whether the characters are written directly to the output sequence without callingxsputn
.-2- Returns:xsputn(s, n)
.