销毁静态存储持续时间对象和未定义的行为

destruction of static storage duration objects & undefined behavior

本文关键字:未定义 对象 静态 存储 持续时间      更新时间:2023-10-16

c++标准第3.6.1节规定

调用在<cstdlib>中声明的函数std::exit(int)终止程序不会离开当前块,因此不会销毁所有具有自动存储期限的对象在对象的销毁过程中被调用来结束程序静态存储期间,程序有未定义行为。

那么,考虑下面这个简单的程序

#include <iostream>
#include <cstdlib>
class test
{
    public:
        test()
        {
            std::cout<<"constructorn";
        }
        ~test()
        {
            std::cout<<"destructorn";
        }
};
int main()
{
    test t;
    exit(0);
}

上面程序的输出显然应该是

构造函数

那么,我的问题是:

  1. 自动对象t何时会被销毁?

  2. 编译器会安全地销毁它吗?

  3. 为什么是未定义行为?

现在,考虑上面程序的稍微修改版本。

#include <iostream>
#include <cstdlib>
class test
{
    public:
        test()
        {
            std::cout<<"constructorn";
        }
        ~test()
        {
            std::cout<<"destructorn";
        }
};
int main()
{
    static test t;
    exit(0);
}

现在,我得到以下输出:

构造函数

析构函数

所以,有可能看到只有构造函数调用作为输出在一些c++实现由于未定义的行为?

如果我理解错了,请纠正我。

  1. 自动对象何时会被销毁?

从来没有。你引用的那句话是"……没有销毁任何具有自动存储持续时间的对象…"

  • 编译器会安全地销毁它吗?
  • 。编译器的工作是生成供机器运行的代码,一旦你进入运行时,编译器就不再做任何事情了。

  • 为什么是未定义行为?
  • 在您的示例中,这不是未定义的行为-您没有在"销毁具有静态或线程存储持续时间的对象"期间调用std::exit()。然而,如果您是,那么回答"这是未定义的行为,因为标准明确地说明了这一点"就足够了。