This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

### 419. istream extractors not setting `failbit` if `eofbit` is already set

Section: 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()` is `true` `false`, calls `is.setstate(failbit)`. Otherwise prepares for formatted or unformatted input. ...