GCC 4.7 istream::tellg() возвращает -1 после достижения EOF

Следующий код работает с gcc 4.4.
Но gcc 4.7 даст ошибку утверждения.

#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;
}

В gcc 4.7, если istream достиг EOF, tellg() вернет -1. в gcc 4.4 это не вызывает ни pubseekoff(), ни seekoff (), это не проблема.

Каким должно быть поведение, gcc 4.4 или gcc 4.7? Зачем?

2 ответа

Решение

В соответствии с C++11 раздел 27.7.2.3p40,

если fail() != false, возвращает pos_type(-1)

Таким образом, gcc 4.7 имеет правильное поведение для текущей версии C++ (при условии, что peek() в конце потока вызывает failbit быть установленным, и это происходит во время постройки, так как skipws устанавливается по умолчанию).

Глядя на формулировку C++03, это то же самое. 27.6.1.3p37. Поэтому поведение, которое вы описываете в gcc 4.4, является ошибкой.

Точнее, eofbit не вызовет tellg() возвращать -1, Но тот факт, что вы читаете прошлое EOF устанавливает failbit, а также tellg() вернусь -1 если badbit или же failbit установлены.

Решение состоит в том, чтобы очистить флаги состояния перед вызовом tellg():

iss.clear();
iss.tellg();  // should work
Другие вопросы по тегам