此代码:
#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;
}
在gcc-4.4.5中提供以下输出
1
4 4
4 4
即。 tellg和tellp都返回了预期的流位置4。
而gcc-4.6.0
给出:
1
4 4
-1 4
我在哪里可以找到告诉的参考:
答案 0 :(得分:5)
好吧,这不是一个错误,即使它似乎是必需的行为:
根据C ++ 2003标准:
tellg():( 27.6.1.3)
构造一个sentry对象后,如果fail()!= false,则返回pos_type(-1)表示失败。否则,返回rdbuf() - &gt; pubseekoff(0,cur,in)。
哨兵(27.6.1.1.2):
如果noskipws为零且is.flags()&amp; ios_base :: skipws非零,函数 只要下一个可用输入字符c是空白字符,每个字符就会提取并丢弃它们。如果is.rdbuf() - &gt; sbumpc()或is.rdbuf() - &gt; sgetc()返回traits :: eof(),则函数调用setstate(failbit | eofbit)(可能会抛出ios_base :: failure)
所以基本上
所以gcc-4.6似乎行为正确......
答案 1 :(得分:2)
我可以确认区别。但是,不是编译器的区别,它不是标准库头的区别,而是链接共享库的区别。
它不依赖于gcc版本。它不依赖于架构:
t44: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
t45: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
t46: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
真正的区别似乎是
$ uname -a
Linux natty 2.6.38-8-generic #42-Ubuntu SMP Mon Apr 11 03:31:24 UTC 2011 i686 GNU/Linux
$ for a in t4?; do ./$a; done
1
4 4
4 4
1
4 4
4 4
1
4 4
4 4
Linux natty 2.6.38-8-generic #42-Ubuntu SMP Mon Apr 11 03:31:24 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
sehe@natty:/mnt/jail/home/sehe$ for a in t4?; do ./$a; done
1
4 4
-1 4
1
4 4
-1 4
1
4 4
-1 4
答案 2 :(得分:2)
好的,与版本分析分开,我将留下一个好的衡量标准,这就是答案:
我将尝试查找源代码,但此主题讨论了由于此更改是否需要更新文档。因此,记录在案的变更:)
修改只找到了这个:libstdc++/26211 (again) + N3168
从此页面:http://gcc.gnu.org/ml/libstdc++/2011-04/msg00026.html
嘿,所有。我最近开始使用gcc-4.6.0而且似乎是行为了 当(仅)设置eofbit时,std :: istream :: tellg()已更改。一世 设法追踪到PR / 26211,我没有辩论 变化。
我花了一段时间才弄清楚出了什么问题,因为它已经过氧化了 对于tellg()说:
If fail() is not false, returns pos_type(-1) to indicate failure. Otherwise returns rdbuf()->pubseekoff(0,cur,in).
Langer和Kreft说的几乎一字不差,所以我就是 假设DR60改为27.6.1.3第37段导致了这一点 改变libstdc ++行为。
是否应该更新libstdc ++ doxygen来说明 事实上,
tellg()
时eof()
也会返回pos_type(-1)
(因为它构造了一个哨兵)?还有其他吗? 功能也应该有更新的文档作为结果 DR60?