【问题标题】:Using cout in destructors of static objects在静态对象的析构函数中使用 cout
【发布时间】:2014-03-23 18:41:45
【问题描述】:

鉴于我的代码的这个精简版本:

#include <iostream>

using namespace std;

struct S {
  S( ostream &os ) : os_( os ) { }
  ~S() { os_ << "The end.\n"; }         // line 7
  ostream &os_;
};

void f() {
  static S s( cout );
  (void)s;
}

int main() {
  f();
  return 0;
}

程序打印The end. 但是,作为更大程序的一部分,它在尝试写入ostream 时会出现SEGFAULTS。

我正在尝试确保某些文本将在程序终止时始终打印出来。我尝试使用 iostreams 做的事情合法吗?使用atexit(3)会更好吗?

我认为因为cout是在我使用它之前构建的,所以它会在我使用之后被销毁;所以不清楚为什么上面的代码不应该总是有效。

更新

如果我将第 7 行更改为直接写入 cout 而不是通过引用,它工作正常。这更离奇。

【问题讨论】:

  • 持有对您无法控制其生命周期的对象的引用对我来说似乎是个坏主意。
  • @JonathanPotter std::cout 是静态的,就像 S 的实例一样,这就是他询问行为的原因。
  • 静态对象的创建和销毁没有明确的顺序,因此当另一个静态对象被销毁时,您不能依赖cout
  • 什么?我认为静态对象的销毁总是按照构造的相反顺序进行的。
  • 我不确定标准对此有何规定,但我知道有些编译器不会考虑将引用传递为“首次使用”。必须实际访问该对象。 gcc 是最大的违规者,尽管我不确定最新版本。

标签: c++ destructor iostream static-variables


【解决方案1】:

如果你在构造静态对象之后调用atexit(),那么静态对象将在调用该对象之后被销毁。所以是的,使用atexit() 应该可以解决问题。

Order between destruction of global object and atexit in C++

【讨论】:

    猜你喜欢
    • 2012-12-26
    • 1970-01-01
    • 2020-12-25
    • 1970-01-01
    • 2015-01-10
    • 2011-05-20
    • 1970-01-01
    相关资源
    最近更新 更多