【问题标题】:destruction of static storage duration objects & undefined behavior静态存储持续时间对象的破坏和未定义的行为
【发布时间】:2015-08-09 21:45:37
【问题描述】:

C++ 标准第 3.6.1 节这样说

调用<cstdlib>中声明的函数std::exit(int)终止 程序没有离开当前块,因此没有 销毁具有自动存储持续时间的任何对象 If 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. 自动对象t什么时候销毁?

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

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

现在,考虑对上述程序稍作修改的版本。

#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++ 实现的输出?

如果我理解不正确,请纠正我。

【问题讨论】:

  • 旁注:调用 exit 是为了程序员的利益。

标签: c++ destructor undefined-behavior


【解决方案1】:
  1. 自动对象t什么时候销毁?

从来没有。您引用的引文是“...... 破坏任何具有自动存储持续时间的对象......”

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

没有。编译器的工作是生成机器运行的代码,一旦你在运行时,编译器就不再做任何事情了。

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

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

【讨论】:

  • @meet 否。重新阅读 UB 的条件 - 你没有在 在销毁期间调用它
猜你喜欢
  • 2015-04-28
  • 1970-01-01
  • 2018-04-23
  • 2018-02-26
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
相关资源
最近更新 更多