By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,369 Members | 1,138 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,369 IT Pros & Developers. It's quick & easy.

C++ exceptions and destructors

P: n/a
Hi!

I've got a question concerning C++ exceptions, more precisely the
stack unwinding when an exception occurs. We agree that when an
exception is thrown, all objects that have destructors are
"destructed" by calling the corresponding destructor. This is most
often what is wanted. However,I have a special situation where this is
NOT what I'd like to happen : indeed, i'd like to keep my objects
living on the stack. Practically, this would be to implement a
function tracing method that would be able, when my program crashes
(exception !), to tell me in which function it happened, just like
unreal.
Is there a way of telling the compiler that an object should not be
destroyed upon exception ? Or, is there a way to know that the
destructor gets called because of an exception and not because the
function exited "normally" ?

Thanks in advance !
Magalie
Jul 19 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Magalie escribió:
Is there a way of telling the compiler that an object should not be
destroyed upon exception ? Or, is there a way to know that the
destructor gets called because of an exception and not because the
function exited "normally" ?


You can allocate the object with new and delete it just before the
function exits... and take care when you add a new "return" to the
function.

Alternatively, you can have an object of a handle class that in his
destructor checks std::uncaught_exception () and destroys or not the
object handled in each case.

In any case you probably need also a way to store pointers to the
allocated and not deleted objects.

Regards.
Jul 19 '05 #2

P: n/a
Hi,
"Magalie" <do**********@laposte.net> wrote in message
news:3f**************************@posting.google.c om...
[....all ok....]
Practically, this would be to implement a
function tracing method that would be able, when my program crashes
(exception !), to tell me in which function it happened, just like
unreal.
Is there a way of telling the compiler that an object should not be
destroyed upon exception ? No, except by allocating it on the heap and manually destroying it
upon function exit. Or, is there a way to know that the
destructor gets called because of an exception and not because the
function exited "normally" ?

Well, there is a function called uncaught_exception() which
returns a boolean. Unfortunately, it cannot be used reliably:
http://www.gotw.ca/gotw/047.htm

So regarding what you are trying to implement, here's what I
would suggest:
If you are ok with using platform-specific features,
some compilers do provide a way to access information
about enclosing stack frames in debug mode. Please ask
in a forum dedicated to your platform.
Alternatively, information about the enclosing calls
should be made available to the exception-throwing code.

Here's a quick overview of what I would try:

class ScopeInfo {
private:
static ScopeInfo* head; // or use TLS for threaded app
//NB: don't forget define&init in a cpp file...
ScopeInfo* const next;
char const* const info;
ScopeInfo(ScopeInfo const&); // not-implemented
public:
ScopeInfo(char const* info_)
: next(head), info(info_) { head=this; };
~ScopeInfo() { head=next; }

static print() {
std::cerr << " In scope:\n";
for( ScopeInfo* p = head ; p ; p=p->next )
std::cerr << p->info << '\n';
}
};

- ScopeInfo are instantiated on the stack as desired
- on throw location, call ScopeInfo::print (or store
the info within the exception)

That's just an option I can think of -- I'm curions
if there are any other ideas...
Cheers,
Ivan
--
http://www.post1.com/~ivec
Jul 19 '05 #3

P: n/a

"Magalie" <do**********@laposte.net> wrote in message news:3f**************************@posting.google.c om...>
. However,I have a special situation where this is
NOT what I'd like to happen : indeed, i'd like to keep my objects
living on the stack.
There is no way to do this. The stack containing these objects
ceases to exist once the catch block is reached.
Practically, this would be to implement a
function tracing method that would be able, when my program crashes
(exception !), to tell me in which function it happened, just like
unreal.
So why don't you put special code in the destructors to record this information?
Is there a way of telling the compiler that an object should not be
destroyed upon exception ?
No.
Or, is there a way to know that the
destructor gets called because of an exception and not because the
function exited "normally" ?


One scheme that I have used to implement a similar feature is to use
a special exception object that I throw, that when it is constructed sets
a static bool that says I'm handling exceptions, then the TraceBack objects
check that in their destructor and if so log their destruction.

A few macros that initalizie the TraceBack object with __FILE__ and __LINE__
give more information on the trace.
Jul 19 '05 #4

P: n/a

Magalie wrote:

Hi!

I've got a question concerning C++ exceptions, more precisely the
stack unwinding when an exception occurs. We agree that when an
exception is thrown, all objects that have destructors are
"destructed" by calling the corresponding destructor.
"We" don't agree. This only makes sense if there's a handler (in
the dynamic context) to catch AND HANDLE your exception -- you'd
really want to fully unwind the stack then (and only then).
This is most
often what is wanted. However,I have a special situation where this is
NOT what I'd like to happen : indeed, i'd like to keep my objects
living on the stack.
Uncaught exception shall invoke unexpected() without any stack
unwinding. The only problem is that unexpected() is {currently}
invoked only on ES violation, AFTER silly unwinding, and with
totally messed up terminate() and unexpected() handlers.

http://groups.google.com/groups?selm...16EC0%40web.de
(Subject: Re: A few exception questions)
Practically, this would be to implement a
function tracing method that would be able, when my program crashes
(exception !), to tell me in which function it happened, just like
unreal.


Do you know what "core dumped" mean? Or are you on a Sutter's
"platform"? ``Hear hear.''

http://search.microsoft.com/search/r...px?qu=Userdump

regards,
alexander.
Jul 19 '05 #5

P: n/a

"Magalie" <do**********@laposte.net> wrote in message
news:3f**************************@posting.google.c om...
Hi!

I've got a question concerning C++ exceptions, more precisely the
stack unwinding when an exception occurs. We agree that when an
exception is thrown, all objects that have destructors are
"destructed" by calling the corresponding destructor. This is most
often what is wanted. However,I have a special situation where this is
NOT what I'd like to happen : indeed, i'd like to keep my objects
living on the stack. Practically, this would be to implement a
function tracing method that would be able, when my program crashes
(exception !), to tell me in which function it happened, just like
unreal.
Is there a way of telling the compiler that an object should not be
destroyed upon exception ? Or, is there a way to know that the
destructor gets called because of an exception and not because the
function exited "normally" ?


I think the normal way to do that would be to add that information to a
parameter passed on the exception itself. For example

void functionA()
{
throw "Error in functionA";
}

Of course, you can get more sophisticated and throw exceptions of your own
classes, with more information inside them.
Jul 19 '05 #6

P: n/a
> We agree that when an
exception is thrown, all objects that have destructors are
"destructed" by calling the corresponding destructor.
No, this is not what happens. Destructors are called only when
objects go out of scope, or delete is called on object created with
new. Consider the following..

#include <iostream>

class foo
{
std::string s_;
public:
foo(std::string s):s_(s) {}
~foo() { std::cout << s_ << "'s ~foo()"<< std::endl;}
};

int main(int argc , char * argv[])
{
try
{
foo * f ( new foo("f") );
foo x("x");
throw 1;
}
catch(int e)
{
std::cout << "in catch, e=" << e << std::endl;
}
}
When executed, it prints...

x's ~foo()
in catch, e=1

The destructor for the object pointed to by f doesn't get called
because it never goes out of scope. That's why they implemented
auto_ptr. Its used like this...

#include <iostream>
#include <memory>

class foo
{
std::string s_;
public:
foo(std::string s):s_(s) {}
~foo() { std::cout << s_ << "'s ~foo()"<< std::endl;}
};

int main(int argc , char * argv[])
{
try
{
std::auto_ptr<foo> f( new foo("f") );
foo x("x");
throw 1;
}
catch(int e)
{
std::cout << "in catch, e=" << e << std::endl;
}
}
When run, it prints the following...
x's ~foo()
f's ~foo()
in catch, e=1

This is most
often what is wanted. However,I have a special situation where this is
NOT what I'd like to happen : indeed, i'd like to keep my objects
living on the stack.
This can only happen if those object don't go out of scope. Like
this...

#include <iostream>
#include <memory>

class foo
{
std::string s_;
public:
foo(std::string s):s_(s) {}
~foo() { std::cout << s_ << "'s ~foo()"<< std::endl;}
};

int main(int argc , char * argv[])
{
std::auto_ptr<foo> f( new foo("f") );
foo x("x");

try
{
throw 1;
}
catch(int e)
{
std::cout << "in catch, e=" << e << std::endl;
}
}
This prints the following

in catch, e=1
x's ~foo()
f's ~foo()

Thus, the object x and f are still on the stack when the exception is
caught.
Practically, this would be to implement a
function tracing method that would be able, when my program crashes
(exception !), to tell me in which function it happened, just like
unreal.
If you load the core file produced when your program crashes into a
debugger, you will get the same information.
Is there a way of telling the compiler that an object should not be
destroyed upon exception ?


The compiler doesn't destroy anything just because of an exception
being thrown, in fact you need to make sure that you destroy things
that need to be destroyed yourself, that's why auto_ptr is so nice.
Basically, the compiler only destroyes objects which go out of scope.
Jul 19 '05 #7

P: n/a

"Big Brian" <wo**@brianmielke.com> wrote in message
news:d2*************************@posting.google.co m...
We agree that when an
exception is thrown, all objects that have destructors are
"destructed" by calling the corresponding destructor.


No, this is not what happens. Destructors are called only when
objects go out of scope, or delete is called on object created with
new.


But that is exactly what happens as the stack unwinds. Surely, the original
poster did not literally mean "all objects" - he/she meant all objects
"below" the catch in scope. I doubt anyone thinks all objects at the same
scope as the exception handler are also wiped out.
Jul 19 '05 #8

P: n/a

"jeffc" <no****@nowhere.com> wrote in message news:3f********@news1.prserv.net...

But that is exactly what happens as the stack unwinds. Surely, the original
poster did not literally mean "all objects" - he/she meant all objects
"below" the catch in scope. I doubt anyone thinks all objects at the same
scope as the exception handler are also wiped out.


Well actually, everything in the try block and things descended from it. It certainly
does not destroy things in the scope of the exception handler (they ahven't been
created yet).

SomeClass A;
try {
SomeClass B;
function_call();
} catch(...) {
SomeClass C;
}

WHen the catch begins, A is still valid, B and everyting in function_call and beyond
is destroyed, C has not yet been created.

Jul 19 '05 #9

P: n/a

"Ron Natalie" <ro*@sensor.com> wrote in message
news:3f***********************@news.newshosting.co m...

"jeffc" <no****@nowhere.com> wrote in message news:3f********@news1.prserv.net...

But that is exactly what happens as the stack unwinds. Surely, the original poster did not literally mean "all objects" - he/she meant all objects
"below" the catch in scope. I doubt anyone thinks all objects at the same scope as the exception handler are also wiped out.
Well actually, everything in the try block and things descended from it.

It certainly does not destroy things in the scope of the exception handler (they ahven't been created yet).


Right, I should have said that in terms of the try block, not the catch.
Jul 19 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.