473,388 Members | 1,376 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

C++ exceptions and destructors

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
9 3294
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
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

"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

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

"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
> 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

"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

"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

"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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: David Turner | last post by:
Hi all I noticed something interesting while testing some RAII concepts ported from C++ in Python. I haven't managed to find any information about it on the web, hence this post. The problem...
7
by: Michael Andersson | last post by:
Hi! Does the use of exception handling induce a performance penalty during the execution of non exception handling code? Regards, /Michael
12
by: Siemel Naran | last post by:
(1) About std::exit. If I call this function, will the system call the destructors of all objects in the call stack. Eg. void f() { std::exit(1); } void g() { X x; f(); } Does the call in...
21
by: mihai | last post by:
People say that is a bad technique to throw exception from constructors; and that the solution would be to create a function _create_ to initialize an object. What about copy constructors? How...
59
by: kk_oop | last post by:
Hi. I wanted to use exceptions to handle error conditions in my code. I think doing that is useful, as it helps to separate "go" paths from error paths. However, a coding guideline has been...
15
by: Bernard | last post by:
Hi All, I am not sure if I should be asking this question on clc or clc++. Let me try on both. I hope that this is not too trivial for the brilliant minds over here. I know that OOP questions...
40
by: Mark P | last post by:
I'm implementing an algorithm and the computational flow is a somewhat deep. That is, fcn A makes many calls to fcn B which makes many calls to fcn C, and so on. The return value of the outermost...
42
by: Jon Harrop | last post by:
Why are exceptions in C++ ~6x slower than exceptions in OCaml? -- Dr Jon D Harrop, Flying Frog Consultancy Objective CAML for Scientists...
5
by: Rennie deGraaf | last post by:
I know that if an exception is thrown from a destructor while unwinding the stack because of another exception, terminate() is called (FAQ 17.3). How exactly does this rule work? Is it acceptable...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.