c++ - Incorrect stack unwinding when exception is thrown
- stevetao <stevetao_member pathlink.com> Mar 26 2002
- Jan Knepper <jan smartsoft.cc> Mar 26 2002
- SteveTao <SteveTao_member pathlink.com> Mar 26 2002
- Jan Knepper <jan smartsoft.cc> Mar 26 2002
- "Walter" <walter digitalmars.com> Mar 26 2002
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 thrown
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
exception is thrown during the operator new []. I originally guessed that
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









Jan Knepper <jan smartsoft.cc> 