ISO/ IEC JTC1/SC22/WG21 N3168

Problems with Iostreams Member Functions (Amended from US 137)

SC22/WG21/N3168
Date: 2010-10-14
Author: P.J. Plauger

There are several problems with member functions in basic_istream and
basic_ostream:

-- putback is obliged to fail at end of file. Moreover, the member function
doesn't clear eofbit, as it should.

The current wording says:

Effects: Behaves as an unformatted input function (as described in 27.7.1.3,
paragraph 1). After constructing a sentry object, if !good() calls
setstate(failbit) which may throw an exception, and return.

Both problems can be solved by first clearing eofbit:

CHANGE 27.7.1.3/34 (putback) first sentence from:

Behaves as an unformatted input function (as described in 27.7.1.3, paragraph
1).

TO:

Behaves as an unformatted input function (as described in 27.7.1.3, paragraph
1), except that the function first clears eofbit.

-- A similar problem exists with unget, with a similar fix:

CHANGE 27.7.1.3/36 (unget) first sentence from:

Behaves as an unformatted input function (as described in 27.7.1.3, paragraph
1).

TO:

Behaves as an unformatted input function (as described in 27.7.1.3, paragraph
1), except that the function first clears eofbit.

-- A similar problem exists with both overloads of seekg, with a similar fix:

CHANGE 27.7.1.3/41 (seekg) first sentence from:

Behaves as an unformatted input function (as described in 27.7.1.3, paragraph
1), except that it does not count the number of characters extracted and does
not affect the value returned by subsequent calls to gcount().

TO:

Behaves as an unformatted input function (as described in 27.7.1.3, paragraph
1), except that the function first clears eofbit, it does not count the
number of characters extracted and does not affect the value returned by
subsequent calls to gcount().

SIMILARLY for 27.7.1.3/43 (seekg).

-- The first overload of seekg ends with the sentence:

In case of failure, the function calls setstate(failbit) (which may throw
ios_base::failure). This sentence is missing in the description of the second
overload, for no good reason that I can detect. The fix is to add the
sentence:

CHANGE 27.7.1.3/43 (seekg) by ADDING at the end of the paragraph:

In case of failure, the function calls setstate(failbit) (which may throw
ios_basefailure).

NOTE: These two preceding changes also address US 139, and IMO provide an
acceptable resolution.

-- The basic_ostream seek functions, seekp and tellp say nothing about
constructing a sentry object. But these functions need such protection just
as much as seekg and tellg, which do. The fix is to add a sentence:

AFTER 27.7.2.5 basic_ostream seek members, ADD:

Each seek member function begins execution by constructing an object of class
sentry. It returns by destroying the sentry object.

--- The question was raised in Rapperswil whether we should also clear
eofbit in seekp. Traditionally, the ostream functions don't touch eofbit.
Hence, pure output to a stream won't set it. If a program is intermixing
reads and writes on the same stream, which is possible but delicate, then
it should probably manage eofbit itself.

The same is true of fstream, sstream, and strstream.

Thus, I make no recommendations to change seekp.