libc ++: почему поток все еще хорош после закрытия - PullRequest
0 голосов
/ 02 июля 2018

У меня очень простая программа

#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), но всегда одинаково. Кто-нибудь может объяснить мне ситуацию здесь? Также содержимое файла не было обновлено, потому что уже закрыто. Почему поток все еще хорош после закрытия и дальнейшей работы?

1 Ответ

0 голосов
/ 04 июля 2018

Я подозреваю, что происходит, когда операции вставляют данные в 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, тогда первая запись завершится неудачно, что говорит о том, что мой анализ верен. Тем не менее, я до сих пор не нашел ничего в стандарте о том, что это «должно» делать. ]

...