Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
March 26, 2002 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; } |
March 26, 2002 Re: Incorrect stack unwinding when exception is thrown | ||||
---|---|---|---|---|
| ||||
Posted in reply to stevetao | 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;
> }
|
March 26, 2002 Re: Incorrect stack unwinding when exception is thrown | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jan Knepper | 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 > |
March 26, 2002 Re: Incorrect stack unwinding when exception is thrown | ||||
---|---|---|---|---|
| ||||
Posted in reply to SteveTao | 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
|
March 26, 2002 Re: Incorrect stack unwinding when exception is thrown | ||||
---|---|---|---|---|
| ||||
Posted in reply to SteveTao | 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 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 > > > > |
Copyright © 1999-2021 by the D Language Foundation