c++ - Incorrect stack unwinding when exception is thrown
- stevetao (110/110) Mar 26 2002 DM 8.27 does not correctly unwind the stack when exception is thrown. T...
- Jan Knepper (5/115) Mar 26 2002 I am not sure if this is stack unwinding or the fact that you throw an
- SteveTao (13/17) Mar 26 2002 The code I provided was to demonstrate that if the exception is thrown d...
- Jan Knepper (4/15) Mar 26 2002 The code shows that.
- Walter (6/26) Mar 26 2002 Thanks for posting the bug, I'll add it to the bug list. -Walter
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.The code shows that. I also noticed that it worked differently with other compilers. Jan
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 thrownduringthe 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 objectsif theexception is thrown during the operator new []. I originally guessed thattheproblem 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