failbit
if eofbit
is already setSection: 31.7.5.2.4 [istream.sentry] Status: C++11 Submitter: Martin Sebor Opened: 2003-09-18 Last modified: 2021-06-06
Priority: Not Prioritized
View all other issues in [istream.sentry].
View all issues with C++11 status.
Discussion:
[istream::sentry], p2 says that istream::sentry
ctor prepares for input if is.good()
is true. p4 then goes on to say that the ctor sets the sentry::ok_
member to
true if the stream state is good after any preparation. 31.7.5.3.1 [istream.formatted.reqmts], p1 then
says that a formatted input function endeavors to obtain the requested input
if the sentry's operator bool()
returns true.
Given these requirements, no formatted extractor should ever set failbit
if
the initial stream rdstate() == eofbit
. That is contrary to the behavior of
all implementations I tested. The program below prints out
eof = 1, fail = 0 eof = 1, fail = 1
on all of them.
#include <sstream> #include <cstdio> int main() { std::istringstream strm ("1"); int i = 0; strm >> i; std::printf ("eof = %d, fail = %d\n", !!strm.eof (), !!strm.fail ()); strm >> i; std::printf ("eof = %d, fail = %d\n", !!strm.eof (), !!strm.fail ()); }
Comments from Jerry Schwarz (c++std-lib-11373):
Jerry Schwarz wrote:
I don't know where (if anywhere) it says it in the standard, but the
formatted extractors are supposed to set failbit
if they don't extract
any characters. If they didn't then simple loops like
while (cin >> x);
would loop forever.
Further comments from Martin Sebor:
The question is which part of the extraction should prevent this from happening
by setting failbit
when eofbit
is already set. It could either be the sentry
object or the extractor. It seems that most implementations have chosen to
set failbit
in the sentry [...] so that's the text that will need to be
corrected.
Pre Berlin: This issue is related to 342. If the sentry
sets failbit
when it finds eofbit
already set, then
you can never seek away from the end of stream.
Kona: Possibly NAD. If eofbit
is set then good()
will return false. We
then set ok to false. We believe that the sentry's
constructor should always set failbit
when ok is false, and
we also think the standard already says that. Possibly it could be
clearer.
[ 2009-07 Frankfurt ]
Moved to Ready.
Proposed resolution:
Change [istream::sentry], p2 to:
explicit sentry(basic_istream<charT,traits>& is , bool noskipws = false);-2- Effects: If
is.good()
istrue
false
, callsis.setstate(failbit)
. Otherwise prepares for formatted or unformatted input. ...