让gcc在终止时刷新所有打开的fstream,就像C流一样

Get gcc to flush all open fstreams upon termination like C streams are

本文关键字:就像 一样 fstream 终止 gcc 刷新      更新时间:2023-10-16

考虑以下代码:

#include <cstdio>
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    ofstream *file1 = new ofstream("file1.txt");
    (*file1) << "hin";
    FILE *file2 = fopen("file2.txt", "w");
    fprintf(file2, "hin");
    abort();
}

file1.txt为空,但file2.txt包含该文本。

是否有任何方法可以确保在程序终止时刷新所有打开的fstream,而不在每次写入后使用std::endl或手动刷新?

gcc版本4.1.2 20080704(Red Hat 4.1.2-54)

当然,没有合法途径。

但在gcc 4.1中,您可以使用__attribute__ ((destructor))进行破解。这将需要使流全局化,并使用exit (-1)而不是abort

整个故事看起来像:

ofstream *file1;
int __attribute__ ((constructor))
pre_exec_fn (void)
{
  file1 = new ofstream("file1.txt");
}
int __attribute__ ((destructor))
post_exec_fn (void)
{
  file1->flush();
  delete file1;
}
int main()
{
    (*file1) << "hin";
    exit(-1);
}

这个解决方案是高度特定于gcc的,在正常情况下不建议使用,但有时它对我很有帮助,特别是在调试时,可以确保程序留下任何日志。

我的观点是Linux或Posix。如果你只想严格遵守语言标准(即C++11),你需要使用构造函数和析构函数。

例如,您可以使用一些智能指针,即使用std::unique_ptr并声明:

 std::unique_ptr<std::ofstream> file1= new ofstream("file1.txt");

我强烈建议使用更新版本的GCC,即g++ 4.9.1版本。您的4.1版本非常旧,不符合C++11标准。

从Linux的角度来看,如果程序以一个信号终止(参见信号(7);请注意,很少有函数可以从信号处理程序合法调用,exit不能,一些信号也不能被捕获,如果没有安装显式信号处理程序,则有几个信号会立即终止进程),通过exit(3)或从main返回(其中出现隐式exit)。

如果你不使用任何智能指针,你也可以注册atexit(3),这是一个退出处理程序函数,它会显式地刷新或关闭程序显式保存在某个地方的所有流(你需要管理如何以及在哪里)。请注意,abort(3)不使用exit(或_exit(2)syscall)

正如Konstantin Vladimirov所回答的,您也可以使用GCC特定的功能属性(例如__attribute__((constructor))

相关文章: