basic_istream::sentry
's constructor ever set eofbit?Section: 31.7.5.2.4 [istream.sentry] Status: TC1 Submitter: Matt Austern Opened: 1999-10-13 Last modified: 2021-06-06
Priority: Not Prioritized
View all other issues in [istream.sentry].
View all issues with TC1 status.
Discussion:
Suppose that is.flags() & ios_base::skipws
is nonzero.
What should basic_istream<>::sentry
's constructor do if it
reaches eof while skipping whitespace? 27.6.1.1.2/5 suggests it
should set failbit. Should it set eofbit as well? The standard
doesn't seem to answer that question.
On the one hand, nothing in [istream::sentry] says that
basic_istream<>::sentry
should ever set eofbit. On the
other hand, 31.7.5.2 [istream] paragraph 4 says that if
extraction from a streambuf
"returns
traits::eof()
, then the input function, except as explicitly
noted otherwise, completes its actions and does
setstate(eofbit)"
. So the question comes down to
whether basic_istream<>::sentry
's constructor is an
input function.
Comments from Jerry Schwarz:
It was always my intention that eofbit should be set any time that a virtual returned something to indicate eof, no matter what reason iostream code had for calling the virtual.
The motivation for this is that I did not want to require streambufs to behave consistently if their virtuals are called after they have signaled eof.
The classic case is a streambuf reading from a UNIX file. EOF isn't really a state for UNIX file descriptors. The convention is that a read on UNIX returns 0 bytes to indicate "EOF", but the file descriptor isn't shut down in any way and future reads do not necessarily also return 0 bytes. In particular, you can read from tty's on UNIX even after they have signaled "EOF". (It isn't always understood that a ^D on UNIX is not an EOF indicator, but an EOL indicator. By typing a "line" consisting solely of ^D you cause a read to return 0 bytes, and by convention this is interpreted as end of file.)
Proposed resolution:
Add a sentence to the end of 27.6.1.1.2 paragraph 2:
If
is.rdbuf()->sbumpc()
oris.rdbuf()->sgetc()
returnstraits::eof()
, the function callssetstate(failbit | eofbit)
(which may throwios_base::failure
).