文件流tellg/tellp和gcc-4.6这是一个bug吗?

Art*_*yom 6 c++ gcc iostream

这段代码:

#include <iostream>
#include <cstdio>
#include <fstream>
#include <string>

int main()
{   
    std::remove("test.txt");
    std::fstream f("test.txt",std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc);
    std::cout << f.good() << std::endl;
    f<<"test"<< std::flush;
    std::cout << f.tellg() << " " << f.tellp() << std::endl;
    f.seekg(0);
    std::string s;
    f>>s;
    std::cout << f.tellg() << " " << f.tellp() << std::endl;
}   
Run Code Online (Sandbox Code Playgroud)

在gcc-4.4.5中给出以下输出

1
4 4
4 4
Run Code Online (Sandbox Code Playgroud)

即tellg和tellp返回预期的流位置4.

而gcc-4.6.0

得到:

1
4 4
-1 4
Run Code Online (Sandbox Code Playgroud)

我在哪里可以找到参考资料:

  1. 第一种情况是正确的(gcc-4.6中的错误)
  2. 第二种情况是正确的(gcc中的错误<gcc-4.6)
  3. 两种情况都是正确的,行为是未定义的

Art*_*yom 5

好吧,它不是一个bug,即使它似乎是必需的行为:

根据C++ 2003标准:

  • tellg():( 27.6.1.3)

    构造一个sentry对象后,如果fail()!= false,则返回pos_type(-1)表示失败.否则,返回rdbuf() - > pubseekoff(0,cur,in).

  • 哨兵(27.6.1.1.2):

    如果noskipws为零且is.flags()&ios_base :: skipws为非零,则只要下一个可用输入字符c是空格字符,该函数就会提取并丢弃每个字符.如果is.rdbuf() - > sbumpc()或is.rdbuf() - > sgetc()返回traits :: eof(),则函数调用setstate(failbit | eofbit)(可能会抛出ios_base :: failure).

所以基本上

  • tellg()创建了sentry对象:
  • 哨兵提取白色空格字符,并应在到达eof后设置failbit.
  • tellg()看到failbit应该返回eof()( - 1)

所以gcc-4.6似乎行为正确......