破坏静态存储持续时间对象&未定义的行为

时间:2015-05-27 16:53:23

标签: c++ destructor undefined-behavior

C ++标准第3.6.1节说

  

调用std::exit(int)中声明的函数<cstdlib>终止   程序没有离开当前块,因此没有   使用自动存储持续时间销毁任何对象如果std :: exit   调用在销毁对象期间结束程序   静态存储持续时间,程序有不确定的行为。

因此,请考虑遵循简单程序

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

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

  

构造

所以,我的问题是:

  1. 何时销毁自动对象?

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

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

  4. 现在,考虑上述程序的略微修改版本。

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

    现在,我得到了以下输出:

      

    构造

         

    那么,由于未定义的行为,是否有可能只将构造函数调用视为某些C ++实现的输出?

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

1 个答案:

答案 0 :(得分:2)

  
      
  1. 当自动对象t被销毁时?
  2.   

从不。你引用的引用是“...... 没有销毁任何具有自动存储持续时间的对象......”

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

没有。编译器的工作是生成要运行的机器的代码,一旦你在运行时编译器不再执行任何操作。

  
      
  1. 为什么它是未定义的行为?
  2.   

在您的示例中,它不是未定义的行为 - 在破坏具有静态或线程存储持续时间的对象期间,您不会调用std::exit()“。但是,如果你是,那么回答“它的未定义行为就足够了,因为标准明确地说明了这一点。”