【问题标题】:Will (global) static variables be destroyed at program end? [duplicate](全局)静态变量会在程序结束时被销毁吗? [复制]
【发布时间】:2012-09-25 13:32:16
【问题描述】:

可能重复:
Does C++ call destructors for global and class static variables?

生命周期是多少

  • 全球MyClass myclass;
  • 全球static MyClass myclass;
  • 全球const MyClass myclass;
  • 全球static const MyClass myclass;
  • 函数本地 static MyClass myclass; 实际发生初始化时
  • C++11 中的全局static constexpr MyClass myclass;

尤其是它们会在常规程序结束时被销毁(即main 不会出现错误)?标准在哪里这样规定。

我注意到 私有析构函数 阻止了所有这些变量的创建。但是,如果我没记错的话,在某处明确提到了一些静态数据可能已被放入静态数据部分并已预先构建加载。这对我来说意味着不会调用任何析构函数。这意味着我可以定义这样一个变量...

【问题讨论】:

  • 你可以在析构函数中加入cout 语句,自己看看。
  • @Beta “试试看”在 C 和 C++ 中经常会因为实现定义和未定义的行为而失败。
  • @Beta 你当然是对的。让我在我的问题中添加我想知道在标准中查看的位置。
  • @delnan: 好点(虽然在这种情况下它定义明确)。

标签: c++ destructor lifetime


【解决方案1】:

具有静态生命周期的对象的析构函数(您在所有情况下 提到定义具有静态生命周期的对象——尽管我不认为 constexpr 中的对象可以具有非平凡的析构函数)是 从exit() 中调用,对象的顺序相反 构建。

main返回导致exit被调用,返回值, 所以从 main 返回会导致这些析构函数被调用。其他 程序终止方式(abort(),断言失败,_exit(), 等)不会调用析构函数。

如果对象在 DLL 中(Unix 下为.so),析构函数将 通常在卸载 DLL 时调用。

【讨论】:

  • 我到底为什么没想到constexpr 中的对象[不能] 有一个重要的析构函数”。不是一个很好的例子,我必须考虑一下。
  • @towi 我完全不确定。我还没有查过,我不确定我必须从哪里开始寻找。但从逻辑上讲:用作constexpr 意味着可以在编译时知道该值,这反过来意味着它是不变的。而一个重要的析构函数将意味着该值将不复存在。
  • @Towi 我刚刚检查过。 constexpr 变量必须具有 文字类型(第 7.1.5/9 节),并且类型要成为文字类型的约束之一是它具有普通析构函数(第 3.9/ 节) 10).
  • +1 表示详细信息,尽管这与注意 C++14 放宽了对 constexpr 的许多限制有关。
【解决方案2】:

文件或命名空间范围对象的析构函数在控制流离开main() 时被调用。

如果一个异常离开main(),那么它的实现定义了是否调用任何对象的析构函数。使用现代编译器,在这种情况下不会调用析构函数,以便在引发未处理的异常时轻松检查程序状态。早期的 C++ 实现使用基于 setjmp/longjmp 的异常机制,该机制会在搜索异常处理程序时展开堆栈,因此即使最终没有找到合适的异常处理程序也会调用析构函数。

如果应用程序以_exit()_Exit()std::quick_exit() 终止,则不会调用析构函数。

【讨论】:

  • 标准规定如果没有捕获到异常,则调用std::terminate()std::terminate(),默认调用abort()。并且abort()不允许调用析构函数。
  • 当然还有:当exit() 被调用时,析构函数被调用。从main 返回会导致调用exit
  • @JamesKanze:好的,谢谢。 Maxim 提到的函数可能在特定实现中,然后调用标准函数。
  • @towi _Exit()std::quick_exit() 是标准 C++;前者也是标准 C。_exit() 是标准 Unix。
  • @JamesKanze:哦,你是对的。发现它是 15.4 和 18.1。在 c++11 标准中。
猜你喜欢
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2016-12-24
  • 2022-01-28
  • 1970-01-01
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
相关资源
最近更新 更多