在具有静态对象的类的析构函数中使用exit()不会像预期的那样结束于无限循环中 [英] Using exit() in destructor of a class having static object, doesn't end up in an infinite loop as expected

查看:215
本文介绍了在具有静态对象的类的析构函数中使用exit()不会像预期的那样结束于无限循环中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在第10章,Bruce Eckel的C ++第1卷中讨论过这个问题。

I came across this in chapter 10, Thinking in C++ vol.1 by Bruce Eckel.


静态对象的析构函数,所有具有静态存储的对象,而不仅仅是上面示例中的局部静态对象)在main()退出时或者当显式调用标准C库函数exit()时被调用。在大多数实现中,main()在终止时调用exit()。这意味着在析构函数中调用exit()可能很危险,因为你可能会遇到无限递归。

Destructors for static objects (that is, all objects with static storage, not just local static objects as in the example above) are called when main( ) exits or when the Standard C library function exit( ) is explicitly called. In most implementations, main( ) just calls exit( ) when it terminates. This means that it can be dangerous to call exit( ) inside a destructor because you can end up with infinite recursion

问题
然后,我自己写了一个代码来模拟这个递归,但我失败了。这是我的代码看起来像。

I also came across this question in SO. Then, I wrote a code myself to simulate this recursion but I failed. Here's how my code looks like.

#include <iostream>
#include <cstdlib>

class Test
{
    private:
        std::string _name;
        static Test obj1;
        static Test obj2;
    public:
        Test(std::string name)
        {
            std::cout << "in constructor:" << name << std::endl;
            _name = name;
        }
        ~Test()
        {
            std::cout << "in destructor:" << _name << std::endl;
            if ("class static 2" == _name)
            {
                std::cout << "calling exit" << std::endl;
                exit(2);
                std::cout << "should not print this" << std::endl;
            }
        }
};

Test global("global");
Test Test::obj1("class static 1");
Test Test::obj2("class static 2");

int main(void)
{
    static Test mainStatic_1("main static");

    return 0;
}

这是我得到的输出,没有任何无限循环

And this is the output I got, without any infinite looping

in constructor:global
in constructor:class static 1
in constructor:class static 2
in constructor:main static
in destructor:main static
in destructor:class static 2
calling exit
in destructor:class static 1
in destructor:global

我的编译器足够聪明吗?我在Ubuntu上使用GCC 4.7.2。

Is my compiler smart enough to handle this? I am using GCC 4.7.2 on Ubuntu.

推荐答案

我确定这是在未定义的行为 。我不能在C ++标准中找到一个段落,但很明显,如果你调用 exit()从发生的事情,因为你调用 exit(),你很可能会陷入无限循环。这是不能保证的,因为全局析构函数的处理可以通过首先从一些列表[1]中删除它,然后调用析构函数来处理要销毁的事物列表。因此,如果 exit 被再次调用,它将处于已经处理该对象的状态。

I'm pretty sure this comes under the heading of "undefined behaviour". I can't find a paragraph in the C++ standard to say so, but it's pretty obvious that if you call exit() from something that happened because you called exit(), chances are that you end up in an infinite loop. It is not guaranteed, because the handling of the global destructors may be done in such a way that the list of things to destroy is dealt with by first removing it from some the list [1], then calling the destructor. So if exit is called again, it will be in a state where it "has already dealt with this object".

标准当然不会说你必须应付 exit()被多次调用 - 很可能另一个C ++库将无法应对这种情况。

The standard certainly doesn't say "You must cope with exit() being called multiple times - so it's quite possible that another C++ library will fail to cope with this.

并且是迂腐的:它不是那么多的编译器作为C ++或经典的C运行时库处理这个。

And being pedantic: It's not so much the compiler as the C++ or classic C runtime library that deals with this.

[1]通过列表,我不是说 std :: list ,而是一个通用的Some一种容纳需要销毁的容器。

[1] By list, I'm not saying std::list, but a generic "Some sort of container holding what needs to be destroyed".

这篇关于在具有静态对象的类的析构函数中使用exit()不会像预期的那样结束于无限循环中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆