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

标签 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;
}

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

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

预期(或使用 libstdc++):

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

我已经在 OSX 和 Xcode 9.4.1(或 Linux)上进行了测试,但总是一样。谁能给我解释一下这里的情况?文件内容也没有更新,因为已经关闭。为什么关闭再运行后流仍然良好

最佳答案

我怀疑正在发生的事情是操作将数据填充到与流关联的 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,那么第一次写入会失败 - 这表明我的分析是正确的。但是,我仍然没有在标准中找到任何关于这个“应该”做什么的内容。 ]

关于c++ - libc++:为什么关闭后流仍然很好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51137052/

相关文章:

c++ - GCC 和 clang 中奇怪的构造和析构函数语法(void * 返回类型)

c++ - 防止 clang-format 将多行 if 语句折叠成单行

c++ - 编译器检测到 allegro.h,但未检测到 allegro_primitives.h

c++ - C++ 不是完全面向对象的语言吗?

c - 海湾合作委员会 : Static array index in function argument doesn't trigger any warning

ubuntu - 如何在 Travis 的 Ubuntu 12.04(精确)上安装 libc++?

c++ - std::map 是否要求比较器的 operator() 为常量?

c++ - 为什么有些包含文件只驻留在 tr1 中?

c++ - 如何将值中对象的属性更改为映射

c++ - 寻找输入的微小变化将导致哈希值发生微小变化的哈希算法