Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC 4.7 istream::tellg() returns -1 after reaching EOF

Tags:

c++

istream

The following code works with gcc 4.4.
But gcc 4.7 will give assertion failure.

#include <assert.h>
#include <iostream>
#include <sstream>

using namespace std;

int main()
{

    string input("abcdefg");
    stringstream iss(input);
    ostringstream oss;
    oss << iss.rdbuf();

    assert (!iss.eof());
    (void) iss.peek();
    assert (iss.eof());

    // the following assertion will fail with gcc 4.7
    assert( streamoff(iss.tellg()) ==
            streamoff(input.length()) );

    return 0;
}

In gcc 4.7, if the istream has reached EOF, tellg() will return -1. no pubseekoff() nor seekoff() will be called In gcc 4.4 it is not a problem.

Which is the supposed to be behavior, gcc 4.4 or gcc 4.7? Why?

like image 827
John Crane Avatar asked Dec 05 '12 20:12

John Crane


2 Answers

According to C++11 section 27.7.2.3p40,

if fail() != false, returns pos_type(-1)

So gcc 4.7 has the correct behavior for the current version of C++ (assuming that peek() at end of stream causes failbit to be set, and it does during sentry construction, since skipws is set by default).

Looking at the wording of C++03, it is the same. 27.6.1.3p37. So the behavior you describe in gcc 4.4 is a bug.

like image 195
Ben Voigt Avatar answered Oct 21 '22 18:10

Ben Voigt


To be precise, eofbit won't cause tellg() to return -1. But the fact that you read past EOF sets the failbit, and tellg() will return -1 if badbit or failbit are set.

The solution is to clear the status flags before calling tellg():

iss.clear();
iss.tellg();  // should work
like image 36
rustyx Avatar answered Oct 21 '22 18:10

rustyx