c++ - 为什么在此代码中忽略了析构函数?

标签 c++ destructor c++builder

以下代码演示了我在 Turbo C++ Explorer 项目中遇到的一个奇怪问题。 D::D() 中的三个堆栈对象之一在超出范围后未被销毁。

只有在 Release模式下编译时才会发生这种情况,auto_ptr a_ 和 b_ 是不同的类型并且抛出的异常不继承自 std::exception。它似乎在 VC++ 2005 和 C++ Builder 2009 中工作得很好。我确实安装了 BDS2006 更新 2、修补程序汇总和修补程序 12。

是我的代码还是编译器?你知道修复吗?不能在 VCL 项目中可靠地使用 auto_ptr 会很不方便。


#include <memory>
#include <stdexcept>
#include <iostream>

typedef std::exception my_error; // will work fine if replaced with line below
//class my_error : public std::exception {};

class A {};
class B {};

class C
{
public:
    C(int id) : id_(id) { std::cout << "C::C() " << id_ << std::endl; };
    ~C() { std::cout << "C::~C() " << id_ << std::endl; };
private:
    int id_;
};

class D
{
public:
    D()
    {
        C c1(1);
        C c2(2);
        C c3(3);

        throw my_error();
    };

private:
    std::auto_ptr<A> a_;
    std::auto_ptr<B> b_; // will work fine if replaced with line below
//  std::auto_ptr<A> b_;
//  std::auto_ptr<C> c_; // see expected output
};

#pragma argsused
int main(int argc, char* argv[])
{
    try
    {
        D d;
    }
    catch (...)
    {
        std::cout << "caught exception" << std::endl;
    }

    return 0;
}


预期:

C::C() 1
C::C() 2
C::C() 3
C::~C() 3
C::~C() 2
C::~C() 1
caught exception


Got:

C::C() 1
C::C() 2
C::C() 3
C::~C() 2
C::~C() 1
caught exception


Got (with line '// std::auto_ptr<C> c_;' uncommented):

C::C() 1
C::C() 2
C::C() 3
C::~C() 1
caught exception


Edit: Made suggested changes

Edit 2:
I just tested it with C++ Builder 2007 (11.0.2902.10471), which shows the same problem. The release configuration works as soon as I check the "Debug information" box in Project -> Options -> C++ Compiler -> Debugging. It surprises me that the executable gets smaller with "Debug information" enabled (down to 31.5 KB from 39.5 KB ).

Edit 3:
In Turbo C++ Explorer (C++ Builder 2006) (10.0.2288.42451) the release configuration works if I uncheck the "Inline function expansion (-vi)" box in Project -> Options -> C++ Compiler -> Debugging. Replacing the first line (#include <memory>) with the following code makes it work, too.

#pragma option push -vi-
#include <memory>
#pragma option pop 

最佳答案

这似乎是一个编译器错误。我刚刚在 VS2008SP1 中运行了相同的示例并获得了预期的输出。

关于c++ - 为什么在此代码中忽略了析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/473720/

相关文章:

c++ - 转换 printf(); cout<<""的语句;陈述。 C&C++

c++ - CudaMalloc 分配内存时失败

c++ - 通过使用特定于平台的项目文件或使用项目生成器来构建自动化?

c++ - 使用 C++ builder 读取 gmail pop3

combobox - 如何使 DBLookupComboBox 鼠标滚轮工作

c++builder - (C++ Builder) DWARF 调试信息在单独的文件中?

c++ - 从 C++ 返回对对象的引用时,是否需要在返回变量中使用 "&"运算符?

C++ 类构造函数/析构函数

c++ - 为什么在这个类中不调用析构函数

C++:在对象范围之外调用析构函数?