Title
seek and eofbit
Status
nad
Section
[istream.unformatted]
Submitter
Howard Hinnant

Created on 2001-10-09.00:00:00 last changed 172 months ago

Messages

Date: 2010-10-21.18:28:33

Rationale:

In C, fseek does clear EOF. This is probably what most users would expect. We agree that having eofbit set should not deter a seek, and that a successful seek should clear eofbit. Note that fail() is true only if failbit or badbit is set, so using !fail(), rather than good(), satisfies this goal.

Date: 2010-10-21.18:28:33

[ Lillehammer: Matt provided wording. ]

Date: 2010-10-21.18:28:33

Proposed resolution:

Change [istream.unformatted] to:

Behaves as an unformatted input function (as described in 27.6.1.3, paragraph 1), except that it does not count the number of characters extracted, does not affect the value returned by subsequent calls to gcount(), and does not examine the value returned by the sentry object. After constructing a sentry object, if fail() != true, executes rdbuf()->pubseekpos(pos). In case of success, the function calls clear(). In case of failure, the function calls setstate(failbit) (which may throw ios_base::failure).

Date: 2010-10-21.18:28:33

[ 2009-07 Frankfurt ]

Moved to NAD. Will reopen if proposed resolution is supplied.

Date: 2001-10-09.00:00:00

I think we have a defect.

According to lwg issue 60 which is now a dr, the description of seekg in [istream.unformatted] paragraph 38 now looks like:

Behaves as an unformatted input function (as described in 27.6.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(). After constructing a sentry object, if fail() != true, executes rdbuf()->pubseekpos( pos).

And according to lwg issue 243 which is also now a dr, 27.6.1.3, paragraph 1 looks like:

Each unformatted input function begins execution by constructing an object of class sentry with the default argument noskipws (second) argument true. If the sentry object returns true, when converted to a value of type bool, the function endeavors to obtain the requested input. Otherwise, if the sentry constructor exits by throwing an exception or if the sentry object returns false, when converted to a value of type bool, the function returns without attempting to obtain any input. In either case the number of extracted characters is set to 0; unformatted input functions taking a character array of non-zero size as an argument shall also store a null character (using charT()) in the first location of the array. If an exception is thrown during input then ios::badbit is turned on in *this'ss error state. If (exception()&badbit)!= 0 then the exception is rethrown. It also counts the number of characters extracted. If no exception has been thrown it ends by storing the count in a member object and returning the value specified. In any event the sentry object is destroyed before leaving the unformatted input function.

And finally 27.6.1.1.2/5 says this about sentry:

If, after any preparation is completed, is.good() is true, ok_ != false otherwise, ok_ == false.

So although the seekg paragraph says that the operation proceeds if !fail(), the behavior of unformatted functions says the operation proceeds only if good(). The two statements are contradictory when only eofbit is set. I don't think the current text is clear which condition should be respected.

Further discussion from Redmond:

PJP: It doesn't seem quite right to say that seekg is "unformatted". That makes specific claims about sentry that aren't quite appropriate for seeking, which has less fragile failure modes than actual input. If we do really mean that it's unformatted input, it should behave the same way as other unformatted input. On the other hand, "principle of least surprise" is that seeking from EOF ought to be OK.

Pre-Berlin: Paolo points out several problems with the proposed resolution in Ready state:

  • It should apply to both overloads of seekg.
  • tellg has similar issues, except that it should not call clear().
  • The point about clear() seems to apply to seekp().
  • Depending on the outcome of 419 if the sentry sets failbit when it finds eofbit already set, then you can never seek away from the end of stream.
History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg2292
2010-10-21 18:28:33adminsetmessages: + msg2291
2010-10-21 18:28:33adminsetmessages: + msg2290
2010-10-21 18:28:33adminsetmessages: + msg2289
2001-10-09 00:00:00admincreate