【问题标题】:libc++: Why is the stream still good after closinglibc++:为什么关闭后流仍然很好
【发布时间】:2018-07-02 13:12:35
【问题描述】:

我有一个非常简单的程序

#include <iostream>
#include <fstream>

void CHECK(std::iostream& s)
{
    std::cout << "good(): "  << s.good()
              << " fail(): " << s.fail()
              << " bad(): "  << s.bad()
              << " eof(): "  << s.eof() << std::endl;
}

int main(int argc, const char * argv[])
{
    std::fstream ofs("test.txt", std::ios::out | std::ios::trunc);
    std::cout << "opened" << std::endl;
    CHECK(ofs);
    ofs << "Hello, World!\n";
    CHECK(ofs);
    ofs.close();
    std::cout << "closed" << std::endl;
    CHECK(ofs);
    ofs << "Hello, World!\n";
    std::cout << "after operation" << std::endl;
    CHECK(ofs);
    return 0;
}

libc++ 我得到以下最后一行:

good(): 1 fail(): 0 bad(): 0 eof(): 0

预期(或libstdc++):

good(): 0 fail(): 1 bad(): 1 eof(): 0

我已经在 OSX 上使用 Xcode 9.4.1(或在 Linux 上)进行了测试,但始终相同。谁能解释一下这里的情况?文件内容也没有更新,因为已经关闭。为什么关闭并进一步操作后流仍然良好

【问题讨论】:

  • 可能是一个错误?发布在 libc++ 列表中
  • 您可以在bugs.llvm.org 提交针对 libc++ 的错误
  • 好的,谢谢 - 我创建了一个ticket

标签: c++ clang libc++


【解决方案1】:

我怀疑正在发生的事情是操作正在将数据填充到与流关联的rdbuf 中。只要缓冲区中有空间,这就成功了。最终,缓冲区已满,流尝试写入文件(已关闭)但失败了。

您可以通过使最后一位循环来测试:

ofs.close();
std::cout << "closed" << std::endl;
CHECK(ofs);
for (int i = 0; i < 500; ++i)
    {
    ofs << "Hello, World!\n";
    std::cout << i << " ";
    CHECK(ofs);
    }
std::cout << "after operation" << std::endl;

在我的机器上,它在大约 300 次后失败 - 并且在那之后永远。 这是正确的行为吗? (甚至符合标准?) 我不知道。

[ 稍后:如果我更改 libc++ 并在关闭时将缓冲区大小设置为 0,那么第一次写入失败 - 这表明我的分析是正确的。但是,我仍然没有在标准中找到关于“应该”做什么的任何内容。 ]

【讨论】:

  • 关于标准一致性,我怀疑关闭它后在流缓冲区上所做的几乎所有事情都是未定义的行为。
  • 可能 - 但我必须研究一下才能确定。
  • 你第一段的解释没有多大意义;关闭文件应该刷新任何缓冲的内容
  • 对,但在那之后,.... 刷新发生后缓冲区是空的。写入它应该没问题,直到将它写入文件。
猜你喜欢
  • 1970-01-01
  • 2014-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-19
  • 1970-01-01
  • 2017-05-19
相关资源
最近更新 更多