255. Why do basic_streambuf<>::pbump() and gbump() take an int?

Section: 30.6.3 [streambuf] Status: NAD Submitter: Martin Sebor Opened: 2000-08-12 Last modified: 2017-06-10

Priority: Not Prioritized

View all other issues in [streambuf].

View all issues with NAD status.

Discussion:

The basic_streambuf members gbump() and pbump() are specified to take an int argument. This requirement prevents the functions from effectively manipulating buffers larger than std::numeric_limits<int>::max() characters. It also makes the common use case for these functions somewhat difficult as many compilers will issue a warning when an argument of type larger than int (such as ptrdiff_t on LLP64 architectures) is passed to either of the function. Since it's often the result of the subtraction of two pointers that is passed to the functions, a cast is necessary to silence such warnings. Finally, the usage of a native type in the functions signatures is inconsistent with other member functions (such as sgetn() and sputn()) that manipulate the underlying character buffer. Those functions take a streamsize argument.

[ 2009-07 Frankfurt ]

This is part of a bigger problem. If anyone cares enough, they should write a paper solving the bigger problem of offset types in iostreams.

This is related to the paper about large file sizes. Beman has already agreed to drop the section of that paper that deals with this.

int is big enough for reasonable buffers.

Move to NAD Future.

This is related to LWG 423.

[2017-02 in Kona, LEWG recommends NAD]

[2017-06-02 Issues Telecon]

Resolve as NAD

The previous rationale given suggested that LWG believes the change is too big for now. Actually, changing the parameter type is too big a change more or less forever, because that would break every custom streambuf type; there are too many such types in the wild to make a breaking change. The overload approach may be more plausible, but is not an entirely breakage-free solution; it can produce ambiguities, and can still break streambuf hierarchies.

Proposed resolution:

Change the signatures of these functions in the synopsis of template class basic_streambuf (27.5.2) and in their descriptions (27.5.2.3.1, p4 and 27.5.2.3.2, p4) to take a streamsize argument.

Although this change has the potential of changing the ABI of the library, the change will affect only platforms where int is different than the definition of streamsize. However, since both functions are typically inline (they are on all known implementations), even on such platforms the change will not affect any user code unless it explicitly relies on the existing type of the functions (e.g., by taking their address). Such a possibility is IMO quite remote.

Alternate Suggestion from Howard Hinnant, c++std-lib-7780:

This is something of a nit, but I'm wondering if streamoff wouldn't be a better choice than streamsize. The argument to pbump and gbump MUST be signed. But the standard has this to say about streamsize (27.4.1/2/Footnote):

[Footnote: streamsize is used in most places where ISO C would use size_t. Most of the uses of streamsize could use size_t, except for the strstreambuf constructors, which require negative values. It should probably be the signed type corresponding to size_t (which is what Posix.2 calls ssize_t). — end footnote]

This seems a little weak for the argument to pbump and gbump. Should we ever really get rid of strstream, this footnote might go with it, along with the reason to make streamsize signed.

Rationale:

The LWG believes this change is too big for now. We may wish to reconsider this for a future revision of the standard. One possibility is overloading pbump, rather than changing the signature.

[ [2006-05-04: Reopened at the request of Chris (Krzysztof Żelechowski)] ]