Stack unwinding

S

Senthilvel

Hi,
The automatic variables declared in the try bock will be destroyed when an
exception is thrown
due to stack unwinding.
So i expected the following code to call the destructor of B but it never
happened.
Am i wrong somewhere or is it my VC++6 compiler giving me problems????

Thanks and Best Regards,
Senthilvel.


#include <iostream>

using namespace std;

struct A
{
A() { cout<< "A's constructor"<<endl;}
~A() { cout<< "A's destructor"<<endl;}
};

struct B
{
B() { cout<< "B's constructor"<<endl;}
~B() { cout<< "B's destructor"<<endl;}
};



void f()
{
A a;
try
{
B b;
int i = 0;
i /= i; // I just wanted to throw some exception
}
catch(out_of_range& err) // I don't want the exception to be caught
here...Lemme catch it in main..
{
err;
}
}


int main()
{
try
{
f();
}
catch(...)
{
cout<<"Exception caught in main!!!"<<endl;
}
return 0;
}


the oputput i get is

A's constructor
B's constructor
A's destructor
Exception caught in main!!!
 
J

John Harrison

Senthilvel said:
Hi,
The automatic variables declared in the try bock will be destroyed when an
exception is thrown
due to stack unwinding.
So i expected the following code to call the destructor of B but it never
happened.
Am i wrong somewhere or is it my VC++6 compiler giving me problems????

Thanks and Best Regards,
Senthilvel.


#include <iostream>

using namespace std;

struct A
{
A() { cout<< "A's constructor"<<endl;}
~A() { cout<< "A's destructor"<<endl;}
};

struct B
{
B() { cout<< "B's constructor"<<endl;}
~B() { cout<< "B's destructor"<<endl;}
};



void f()
{
A a;
try
{
B b;
int i = 0;
i /= i; // I just wanted to throw some exception


Divde by zero is not a C++ exception, its is undefined behaviour.

If you want to see proper stack unwinding throw a proper C++ exception

if (i == 0)
throw "divide by zero";
i /= i;

john
 
P

Peter Koch Larsen

Senthilvel said:
Hi,
The automatic variables declared in the try bock will be destroyed when an
exception is thrown
due to stack unwinding.
So i expected the following code to call the destructor of B but it never

Apart from what John said, i might add that a try block is not needed. A
destructor will be called regardless of whether the variable was declared in
a scope or not.

Kind regards
Peter
happened.
Am i wrong somewhere or is it my VC++6 compiler giving me problems????

Thanks and Best Regards,
Senthilvel.


#include <iostream>

using namespace std;

struct A
{
A() { cout<< "A's constructor"<<endl;}
~A() { cout<< "A's destructor"<<endl;}
};

struct B
{
B() { cout<< "B's constructor"<<endl;}
~B() { cout<< "B's destructor"<<endl;}
};



void f()
{
A a;
try
{ This tryblock is not needed.
B b;
int i = 0;
i /= i; // I just wanted to throw some exception

And (to remind you): division by zero is undefined.
It still puzzles me that B's destructor is not called, though, now that
Microsoft has "enhanced" its exception handling to include such silly stuff.
I would recommend you upgraded your compiler - its age is showing (as it has
since '98 ;-)
 
R

Rolf Magnus

Senthilvel said:
Hi,
The automatic variables declared in the try bock will be destroyed
when an exception is thrown due to stack unwinding.

Actually all automatic variables in the function.
So i expected the following code to call the destructor of B but it
never happened.
Am i wrong somewhere or is it my VC++6 compiler giving me problems????

Thanks and Best Regards,
Senthilvel.


#include <iostream>

For std::eek:ut_of_range, you need:

#include said:
using namespace std;

struct A
{
A() { cout<< "A's constructor"<<endl;}
~A() { cout<< "A's destructor"<<endl;}
};

struct B
{
B() { cout<< "B's constructor"<<endl;}
~B() { cout<< "B's destructor"<<endl;}
};



void f()
{
A a;
try
{
B b;
int i = 0;
i /= i; // I just wanted to throw some exception

Then use an explicit 'throw'. The above is not supposed to throw an
exception.
}
catch(out_of_range& err) // I don't want the exception to be caught
here...

But you do catch it here, and you don't rethrow it, so the exception
shouldn't reach main, and it doesn't on my compiler.
Lemme catch it in main..
{
err;
}
}


int main()
{
try
{
f();
}
catch(...)
{
cout<<"Exception caught in main!!!"<<endl;
}
return 0;
}


the oputput i get is

A's constructor
B's constructor
A's destructor
Exception caught in main!!!

After doing the above mentioned changes, it works as expected and gives
me the output:

A's constructor
B's constructor
B's destructor
A's destructor
Exception caught in main!!!
 
P

Peter van Merkerk

Senthilvel said:
The automatic variables declared in the try bock will be destroyed when an
exception is thrown due to stack unwinding.
So i expected the following code to call the destructor of B but it never
happened.
Am i wrong somewhere or is it my VC++6 compiler giving me problems????

Thanks and Best Regards,
Senthilvel.


#include <iostream>

using namespace std;

struct A
{
A() { cout<< "A's constructor"<<endl;}
~A() { cout<< "A's destructor"<<endl;}
};

struct B
{
B() { cout<< "B's constructor"<<endl;}
~B() { cout<< "B's destructor"<<endl;}
};



void f()
{
A a;
try
{
B b;
int i = 0;
i /= i; // I just wanted to throw some exception
}
catch(out_of_range& err) // I don't want the exception to be caught
here...Lemme catch it in main..
{
err;
}
}


int main()
{
try
{
f();
}
catch(...)
{
cout<<"Exception caught in main!!!"<<endl;
}
return 0;
}


the oputput i get is

A's constructor
B's constructor
A's destructor
Exception caught in main!!!


The problem is in the lines:

int i = 0;
i /= i;

The C++ standard does not specify what should happen in case of a
division by zero. I.e. there is no guarantee that a C++ exception will
be thrown. In this case you probably get an OS exception which is
different from a C++ exception and beyond the scope of the C++ standard.

If you replace those two lines with:

throw "Whatever";

Your code will behave as expected.

Note that MSVC6 is not exactly renowned for its C++ standard compliance.
 
S

Senthilvel

Divde by zero is not a C++ exception, its is undefined behaviour.

If you want to see proper stack unwinding throw a proper C++ exception

if (i == 0)
throw "divide by zero";
i /= i;

john

Thanks John!!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top