libc ++:关闭后为什么流仍然很好

GrE*_*EnE 6 c++ clang libc++

我有一个非常简单的程序

#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;
}
Run Code Online (Sandbox Code Playgroud)

随着libc++我碰到下面的最后一行:

good(): 1 fail(): 0 bad(): 0 eof(): 0
Run Code Online (Sandbox Code Playgroud)

预期(或与libstdc++):

good(): 0 fail(): 1 bad(): 1 eof(): 0
Run Code Online (Sandbox Code Playgroud)

我已经在OSX上使用Xcode 9.4.1(或在Linux上)进行了测试,但总是一样的.谁能解释一下这里的情况?此外,文件内容未更新,因为已经关闭.关闭和进一步操作后,为什么流仍然良好

Mar*_*low 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;
Run Code Online (Sandbox Code Playgroud)

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

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