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?
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(); };
Yes. If the program terminates gracefully the destructors are called to clean up .
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's the order that local objects are destructed? ¶ Δ In reverse order of construction: First constructed, last destructed.
Not without exceptions or returning normally from Err all the way up the callstack. You need to unwind the stack.
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With