iostream sentry doesn't set failbit when it has reached the end

Viewed 555

for the following code:

#include <iostream>
#include <sstream>

using namespace std;

int main() {
    istringstream iss("a");
    iss.get();
    cout << iss.tellg() << endl;  // 1
    cout << iss.fail() << endl;   // 0
}

I'd expect the result be -1,1 not 1, 0.

tellg will first construct a sentry and then check fail().

according to http://eel.is/c++draft/istream::sentry#2

If is.rdbuf()->sbumpc() or is.rdbuf()->sgetc() returns traits​::​eof(), the function calls setstate(failbit | eofbit) (which may throw ios_­base​::​failure).

so fail() should be true, and tellg should return -1.

1 Answers

From the ref of std::istream::tellg:

if member fail returns true, the function returns -1.

From the ref of std::ios::fail:

Check whether either failbit or badbit is set

Returns true if either (or both) the failbit or the badbit error state flags is set for the stream.

At least one of these flags is set when an error occurs during an input operation.

Check with this code:

#include <iostream>
#include <sstream>

using namespace std;

int main() {
    istringstream iss("a");
    iss.get();
    cout << iss.fail() << endl;   // 0
    cout << iss.tellg() << endl;  // 1
    cout << iss.eof() << endl;    // 0
}
Related