The following code demonstrates a weird problem I have in a Turbo C++ Explorer project. One of the three stack objects in D::D() is not destroyed after going out of scope.
This only happens if compiled in release mode, the auto_ptrs a_ and b_ are of different types and the exception thrown doesn’t inherit from std::exception. It appears to work just fine in VC++ 2005 and C++ Builder 2009. I did install the BDS2006 Update 2, the hotfix rollup and hotfix 12.
Is it my code or the compiler? Do you know of a fix? Not being able to reliably use auto_ptr in a VCL project would be quite inconvenient.
#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; }
Expected:
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
This appears to be a compiler bug. I just ran the same sample in VS2008SP1 and got the expected output.