I've read several questions here on Stack Overflow, Microsoft docs, and cplusplus.com. Some claim that exit()
terminates the program normally, just as a return 0;
would from main. Others claim that exit()
doesn't call all the destructors, etc. So I was wondering if someone could help. I link the posts I've read about this:
https://cplusplus.com/forum/beginner/4589/
How to exit program execution in C ?
https://docs.microsoft.com/en-us/cpp/cpp/program-termination?view=msvc-170
https://cplusplus.com/reference/cstdlib/exit/
Thanks in advance
CodePudding user response:
For a call to the C standard function ::exit
or std::exit
, destructors will be called for objects with static storage duration. Note this doesn't apply to other termination functions like _exit()
, abort()
, TerminateProcess()
etc.
The old simple verbiage ([basic.start.term]
) from C 03:
Destructors for initialized objects of static storage duration (declared at block scope or at namespace scope) are called as a result of returning from
main
and as a result of callingexit
In contrast, destructors for automatic storage duration objects are not called by exit()
([basic.start.main]
):
Calling the function
void exit(int);
declared in<cstdlib>
terminates the program without leaving the current block and hence without destroying any objects with automatic storage duration
The contrast with abort()
is also quite insightful:
Calling the function
void abort();
declared in<cstdlib>
terminates the program without executing destructors for objects of automatic or static storage duration and without calling the functions passed toatexit()
.
For dynamically-allocated objects, naturally destructors are only called if the cleanup process for static (and thread-static) storage objects explicitly destroys such objects (typically because they are owned in a smart pointer).
New verbiage: https://eel.is/c draft/basic.start.term still provides for calling destructors, but now contains new rules to handle threads and thread-local objects instead of just static and automatic storage class.
CodePudding user response:
Some claim that exit() terminates the program normally, just as a return 0; would from main
std::exit
gets called anyway, as part of standard application lifecycle. Quote from CPPReference:
Returning from the main function, either by a return statement or by reaching the end of the function performs the normal function termination (calls the destructors of the variables with automatic storage durations) and then executes std::exit, passing the argument of the return statement (or 0 if implicit return was used) as exit_code.
Others claim that exit() doesn't call all the destructors, etc
It's true, but it doesn't cancel the first statement. I.e. if destructors of you classes don't have any side effects that can survive the program, it doesn't matter whether local were destroyed properly or not, since entire memory of your process is freed after program termination. std::exit
however calls destructors of objects with static and thread local storage duration:
The destructors of objects with thread local storage duration that are associated with the current thread, the destructors of objects with static storage duration, and the functions registered with std::atexit are executed concurrently
CodePudding user response:
It is completely unreasonable to assume a program is going to properly fall all the way out of main()
during any form of error handling. In the case of a we should not / can not go any further
, professional programs call exit()
all the time.
However, if you have objects that NEED to be cleaned up, then you need to implement an atexit handler. See: