2012-12-05 11 views
6

Mã sau hoạt động với gcc 4.4.
Nhưng gcc 4.7 sẽ đưa ra lỗi xác nhận.GCC 4.7 istream :: tellg() trả về -1 sau khi đạt EOF

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

Trong gcc 4.7, nếu istream đã đạt đến EOF, tellg() sẽ trả về -1. không pubseekoff() cũng không seekoff() sẽ được gọi là Trong gcc 4.4 nó không phải là một vấn đề.

Hành vi nào là hành vi, gcc 4.4 hoặc gcc 4.7? Tại sao?

+0

Một chút bối rối. Tại sao không phải là 'iss.eof()' đặt sau khi khai thác? –

+0

Nó đã được sửa từ gcc 4.6, ở đây [là báo cáo lỗi] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26211). –

+0

Báo cáo lỗi đó không có quá nhiều mô tả. Các tập tin đã được thay đổi có liên quan với vấn đề hiện tại mặc dù. Làm cách nào bạn liên kết lỗi đó với sự cố hiện tại? –

Trả lời

5

Theo C++ 11 phần 27.7.2.3p40,

nếu fail() != false, trả pos_type(-1)

Vì vậy, gcc 4.7 có hành vi chính xác cho các phiên bản hiện tại của C++ (giả định rằng peek() ở cuối luồng làm cho failbit được đặt và trong quá trình xây dựng sentry, vì skipws được đặt theo mặc định).

Nhìn vào từ ngữ của C++ 03, nó giống nhau. 27.6.1.3p37. Vì vậy, hành vi bạn mô tả trong gcc 4.4 là một lỗi.

1

Để chính xác, eofbit sẽ không gây ra tellg() để trả lại -1. Nhưng thực tế là bạn đọc qua EOF đặt failbittellg() sẽ trả lại -1 nếu badbit hoặc failbit được đặt.

Giải pháp là để xóa các cờ trạng thái trước khi gọi tellg():

iss.clear(); 
iss.tellg(); // should work