Archives
D Programming
DD.gnu digitalmars.D digitalmars.D.bugs digitalmars.D.dtl digitalmars.D.dwt digitalmars.D.announce digitalmars.D.learn digitalmars.D.debugger C/C++ Programming
c++c++.announce c++.atl c++.beta c++.chat c++.command-line c++.dos c++.dos.16-bits c++.dos.32-bits c++.idde c++.mfc c++.rtl c++.stl c++.stl.hp c++.stl.port c++.stl.sgi c++.stlsoft c++.windows c++.windows.16-bits c++.windows.32-bits c++.wxwindows digitalmars.empire digitalmars.DMDScript |
c++ - Incorrect stack unwinding when exception is thrown
DM 8.27 does not correctly unwind the stack when exception is thrown. The result of the following code should be. Composite is created Element no. 1 is created Element no. 2 is created Element no. 3 is created Element no. 4 is created Element no. 5 is created Element no. 6 is created Element no. 5 is destroyed Element no. 4 is destroyed Element no. 3 is destroyed Element no. 2 is destroyed Element no. 1 is destroyed Exception is thrown But DM 8.27 generate the following: Composite is created Element no. 1 is created Element no. 2 is created Element no. 3 is created Element no. 4 is created Element no. 5 is created Element no. 6 is created Exception is thrown The code to demonstrate this problem is #include <iostream.h> struct Exception {}; //-------------------------------------------------------------- class Element { public: Element() { cout << "Element no. " << ++count << " is created\n"; if (count > 5) { --count; throw Exception(); } } virtual ~Element() { cout << "Element no. " << count-- << " is destroyed\n"; } private: static int count; }; int Element::count = 0; //-------------------------------------------------------------- class Composite { public: Composite() { cout << "Composite is created\n"; pE = new Element[10]; } virtual ~Composite() { delete [] pE; cout << "Composite is destroyed\n"; } private: Element *pE; }; //-------------------------------------------------------------- class Base { public: Base() { pC = new Composite; cout << "Constructing base\n"; } virtual ~Base() { delete pC; cout << "Destroying base\n"; } private: Composite *pC; }; //-------------------------------------------------------------- class Derived : public Base { public: Derived() { cout << "Constructing derived\n"; throw Exception(); } virtual ~Derived() { cout << "Destroying derived\n"; } }; //-------------------------------------------------------------- // main //-------------------------------------------------------------- int main() { Base * p; try { p = new Derived; } catch( Exception e) { cout << "Exception is thrown\n"; } return 0; } Mar 26 2002
I am not sure if this is stack unwinding or the fact that you throw an exception during a new [] which does not revert the contructions by destructing the constructed elements. Jan stevetao wrote:DM 8.27 does not correctly unwind the stack when exception is thrown. The result of the following code should be. Composite is created Element no. 1 is created Element no. 2 is created Element no. 3 is created Element no. 4 is created Element no. 5 is created Element no. 6 is created Element no. 5 is destroyed Element no. 4 is destroyed Element no. 3 is destroyed Element no. 2 is destroyed Element no. 1 is destroyed Exception is thrown But DM 8.27 generate the following: Composite is created Element no. 1 is created Element no. 2 is created Element no. 3 is created Element no. 4 is created Element no. 5 is created Element no. 6 is created Exception is thrown The code to demonstrate this problem is #include <iostream.h> struct Exception {}; //-------------------------------------------------------------- class Element { public: Element() { cout << "Element no. " << ++count << " is created\n"; if (count > 5) { --count; throw Exception(); } } virtual ~Element() { cout << "Element no. " << count-- << " is destroyed\n"; } private: static int count; }; int Element::count = 0; //-------------------------------------------------------------- class Composite { public: Composite() { cout << "Composite is created\n"; pE = new Element[10]; } virtual ~Composite() { delete [] pE; cout << "Composite is destroyed\n"; } private: Element *pE; }; //-------------------------------------------------------------- class Base { public: Base() { pC = new Composite; cout << "Constructing base\n"; } virtual ~Base() { delete pC; cout << "Destroying base\n"; } private: Composite *pC; }; //-------------------------------------------------------------- class Derived : public Base { public: Derived() { cout << "Constructing derived\n"; throw Exception(); } virtual ~Derived() { cout << "Destroying derived\n"; } }; //-------------------------------------------------------------- // main //-------------------------------------------------------------- int main() { Base * p; try { p = new Derived; } catch( Exception e) { cout << "Exception is thrown\n"; } return 0; } Mar 26 2002
The code I provided was to demonstrate that if the exception is thrown during the operator new [], the destructor of all created objects must be called. The code was working correctly with the following compilers: 1. Microsoft Visual C++ 6.0 - 7.0 2. Borland C++ 5.02 - 5.5.1 3. GNU GCC 2.95.0 - 3.04 4. Watcom C++ 11.0c 5. Metrowerks CodeWarrior 5 - 7 All these compilers properly called the destructor of all created objects if the exception is thrown during the operator new []. I originally guessed that the problem was due to incorrect stack unwinding. Steve In article <3CA0B5E6.271CE29F smartsoft.cc>, Jan Knepper says...I am not sure if this is stack unwinding or the fact that you throw an exception during a new [] which does not revert the contructions by destructing the constructed elements. Jan Mar 26 2002
SteveTao wrote:The code I provided was to demonstrate that if the exception is thrown during the operator new [], the destructor of all created objects must be called. The code was working correctly with the following compilers: 1. Microsoft Visual C++ 6.0 - 7.0 2. Borland C++ 5.02 - 5.5.1 3. GNU GCC 2.95.0 - 3.04 4. Watcom C++ 11.0c 5. Metrowerks CodeWarrior 5 - 7 All these compilers properly called the destructor of all created objects if the exception is thrown during the operator new []. I originally guessed that the problem was due to incorrect stack unwinding. Mar 26 2002
Thanks for posting the bug, I'll add it to the bug list. -Walter "SteveTao" <SteveTao_member pathlink.com> wrote in message news:a7qe95$13ne$1 digitaldaemon.com...The code I provided was to demonstrate that if the exception is thrown Mar 26 2002
|