Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terminate application AND call the destructors of local objects

I have some objects on the stack in main function:

int main(...)
{
   CFoo foo;
   CBar bar;
}

Also, I have a function, that keeps track of errors in my application:

void Err(std::string msg)
{
   SomehowLogErrorMessage(msg);
   exit(1);
}

Err function is definitely useful when I have to report a fatal error. I just log the error and terminate the application - it cannot recover after such errors. However, terminating with "exit()" does not invoke foo and bar destructors - a behavior, that I actually expected (but was wrong). "abort()" doesn't help either. Also, I cannot use exceptions to catch them in main(). Is there any other way to implement Err function so, that it terminates the app and correctly cleans the stack objects? Or should I somehow redesign my error handling?

Thanks!


p.s. By the way, can't I send WM_QUIT message to my main window? I am not good with WinAPI, but my app is pure Win32 and my Err() function can get a handle to my main window. Will it work?

like image 304
SadSido Avatar asked Apr 11 '11 14:04

SadSido


People also ask

How do you call a destructor of an object?

A destructor is called for a class object when that object passes out of scope or is explicitly deleted. A destructor is a member function with the same name as its class prefixed by a ~ (tilde). For example: class X { public: // Constructor for class X X(); // Destructor for class X ~X(); };

Is a destructor called when the program ends?

Yes. If the program terminates gracefully the destructors are called to clean up .

Does C++ automatically call destructors?

A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete .

What is destructor What's the order in which the local objects are destructed?

What's the order that local objects are destructed? ¶ Δ In reverse order of construction: First constructed, last destructed.


3 Answers

Not without exceptions or returning normally from Err all the way up the callstack. You need to unwind the stack.

like image 178
Logan Capaldo Avatar answered Oct 06 '22 01:10

Logan Capaldo


There's still C's setjmp and longjmp. It should bring you back to main, so the program would terminate as usual after leaving scope of main, in which case C++'s destructor mechanism will destroy your local objects in main.

Of course using longjmp is frowned upon in C++ for good reasons. It will skip any other functions on the stack, so it really works only for a few stack objects in main.

It might be easier to allocate your objects on the heap and delete them manually in Err.

like image 25
Alexander Gessler Avatar answered Oct 05 '22 23:10

Alexander Gessler


There are basically two methods for propagating errors around in C++: Exceptions (which you've seemingly arbitrarily excluded) and return codes.

Since you can't use exceptions, you're going to need to start passing return codes from your functions that may fail and test them to see if you need to stop and return back up to main. If you don't unwind the stack like this there's no way to guarantee that destructors will be called properly.

Also consider that if your program is in a fatal state will destructors actually be able to clean up expectedly? What if the object state is flawed and can't be taken down properly? Instead of calling exit you could call abort which would at least leave a core to help diagnose the problem if you get into a bad state. For fatal errors where exceptions are unavailable this is a reasonable choice.

like image 40
Mark B Avatar answered Oct 06 '22 00:10

Mark B