Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

libc++: Why is the stream still good after closing

Tags:

c++

clang

libc++

I have a very simple program

#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;
}

With libc++ I get the following last line:

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

Expected (or with libstdc++):

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

I have tested on OSX with Xcode 9.4.1 (or on Linux), but always the same. Can anybody explain me the situation here? Also the file content was not updated, because already closed. Why is the stream still good after closing and further operation?

like image 865
GrEnE Avatar asked Jul 02 '18 13:07

GrEnE


1 Answers

What I suspect is happening is that the operations are stuffing the data into the rdbuf associated with the stream. That succeeds, as long as there is room in the buffer. Eventually, the buffer gets full, and the stream attempts to write to the file (which is closed) and that fails.

You can test that by making the last bit a loop:

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;

On my machine, it fails after about 300 - and forever after that. Is this correct behavior? (or even standards-compliant?) I don't know.

[ Later: If I change libc++ do set the buffer size to 0 upon close, then the first write fails - so that suggests that my analysis is correct. However, I still haven't found anything in the standard about what this 'should' do. ]

like image 50
Marshall Clow Avatar answered Sep 27 '22 19:09

Marshall Clow