3

我正在使用 Mac OSX 10.8.1 (Mountain Lion) 和:Apple clang 版本 4.1 (tags/Apple/clang-421.11.66) (基于 LLVM 3.1svn) - 最新可用。

关于 eof 检测,使用 libc++ std::istream::peek() 的 Clang 似乎工作不正确。libstdc++ 没有出现问题。

下面的简单示例根据标准库版本给出不同的结果:

测试.cpp:

#include <iostream>
#include <sstream>

void printstat(std::istream& data) {
  std::cout << "flags:  eof: " << data.eof() << ";  good: " << data.good() << ";  bad: " << data.bad() << "  fail: " << data.fail() << std::endl;
}

int main() {
  std::stringstream data("a"); 
  printstat(data);

  while (data.good()) {
    char a = data.get();
    std::cout << "get(): " << a << std::endl;
    printstat(data);

    data.peek();
    std::cout << "peek()" << std::endl;
    printstat(data);
    std::cout << std::endl;
  }

  return 0;
}

使用“clang++ -stdlib=libstdc++ test.cpp”编译的文件的输出(这看起来正确):

flags:  eof: 0;  good: 1;  bad: 0  fail: 0
get(): a
flags:  eof: 0;  good: 1;  bad: 0  fail: 0
peek()
flags:  eof: 1;  good: 0;  bad: 0  fail: 0

使用“clang++ -stdlib=libc++ test.cpp”编译的文件的输出(这对我来说看起来不正确):

get(): a
flags:  eof: 0;  good: 1;  bad: 0  fail: 0
peek()
flags:  eof: 0;  good: 1;  bad: 0  fail: 0

get(): ?
flags:  eof: 1;  good: 0;  bad: 0  fail: 1
peek()
flags:  eof: 1;  good: 0;  bad: 0  fail: 1

此问题的最简单解决方法似乎是使用 libstdc++ 而不是 libc++。不幸的是,我需要使用一些 c++11 特性,所以 libc++ 是唯一的解决方案。

我在那里发现了一些帖子,它们报告了 libc++ 和 libstdc++ 在 eof 位行为中的差异,但与我的不同。

有没有人遇到和我一样的问题。有没有通用的解决方案来解决它?我可以想象一些肮脏的解决方法,但我宁愿不使用它。

预先感谢您的帮助

4

1 回答 1

1

我很抱歉。这是 libc++ 中的一个错误。它已在 libc++ svn 公共主干中修复,但修复需要重新编译的 libc++.dylib,这是可以理解的,它在 OS X 10.8.y 上不存在。

llvm svn 服务器目前已关闭,但我相信解决方法是简单地检查 eof in basic_istream<_CharT, _Traits>::peek()

+            if (traits_type::eq_int_type(__r, traits_type::eof()))
+                this->setstate(ios_base::eofbit);

正如您已经推测的那样,解决方法是不依赖于 peek 后的准确 eof 检查。

于 2013-01-04T04:04:05.747 回答