End the application and call local object destructors

I have some objects on the stack in the main function:

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

In addition, I have a function that tracks errors in my application:

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

The Err function is definitely useful when I have to report a fatal error. I simply register an error and terminate the application - after such errors it is impossible to recover. However, terminating with the "exit ()" function does not call the destructors foo and bar - the behavior that I really expected (but was wrong). "abort ()" doesn't help either. In addition, I cannot use exceptions to catch them in main (). Is there any other way to implement the Err function so that it terminates the application and correctly clears the stack objects? Or am I somehow redesigning my error handling?

Thanks!


ps By the way, can I send WM_QUIT message to my main window? I am not good at WinAPI, but my application is pure Win32, and my Err () function can get a handle to my main window. Will this work?

+8
c ++ stack windows destructor exit
source share
5 answers

Not with the exception or usually returning from Err to a still image. You need to expand the stack.

+3
source share

There are still C setjmp and longjmp . It should return you to main , so the program will exit as usual after exiting the main , in which case the C ++ destructor mechanism will destroy your local objects in main .

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

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

+2
source share

In C ++, there are two methods for propagating errors: Exceptions (which you seemingly arbitrarily excluded) and return codes.

Since you cannot use exceptions, you will need to start passing the return codes from your functions that may fail, and test them to see if you need to stop and return to the main one. If you do not unwind such a stack, you cannot guarantee that destructors will be called properly.

Also consider that if your program is in a fatal state, can destructors actually wash themselves in anticipation? What if the state of the object is erroneous and cannot be canceled correctly? Instead of calling exit, you can call abort , which at least leaves the kernel to help diagnose the problem if you fall into a bad state. For fatal errors when exceptions are not available, this is a smart choice.

+1
source share

I believe Exit will terminate the application immediately. To see the behavior that you expect foo and bar to go out of scope. This means that the main function would have to end with a return value. Instead of calling Exit() from your Err function, you need to find a way to return to your main function and let it return normally with an error message.

0
source share

I would review your error handling. The simplest task is to control the return to main , and let it perform its usual cleanup. Exceptions provide this capability by expanding the stack, but you cannot use exceptions. Ok, that's fine. Sometimes you just cannot use exceptions.

Therefore, instead of Err trying to disable the program, Err write down the error and return the error code. Ideally, Err should not do two tasks in any case that you are trying to do: 1) Write down the error, 2) Stop the application gracefully.

If your application is multithreaded, you may have bad access. In the error log stream, signal the "die" event. Ask the main thread to wait at this event along with what it is waiting for (or attach a task to it through QueueUserAPC or the like). When the event is signaled, close the application.

0
source share

All Articles