I was trying to figure out the differences between terminate()
, exit()
and abort()
, and Microsoft’s
C++ program termination documentation came up in my Google search that compares exit
vs abort
vs atexit
.
I read the first part that compares exit
and abort
, and it makes sense:
The difference between exit and abort is that exit allows the C++
runtime termination processing to take place (global object destructors get called). abort terminates the program immediately. The abort function bypasses the normal destruction process for initialized global static objects. It also bypasses any special processing that was specified using the atexit function.
Then later, there is a comparison of return
and exit
with this sample code and corresponding explanation:
// return_statement.cpp
#include <stdlib.h>
struct S
{
int value;
};
int main()
{
S s{ 3 };
exit( 3 );
// or
return 3;
}
The exit and return statements in the preceding example have similar behavior. Both terminate the program and return a value of 3 to the operating system. The difference is that exit doesn’t destroy the automatic variable
s
, while the return statement does.
-
I thought that
s
would also be destroyed whenexit()
is called. Did I misunderstand, or is there a mistake? -
If
s
isn’t destroyed, how do we reclaim this memory from the stack? What ifs
were on the heap, would we have leaked this memory, too?
I am not looking for Microsoft-specific solutions. I just found the source and realized that Microsoft does have good documentation for a beginner like me.
5
Global objects are cleanly destructed, but local objects are not. For example, this code:
#include <stdio.h>
#include <stdlib.h>
class Foo {
char const *s;
public:
Foo(char const *s) : s(s) {}
~Foo() { fprintf(stderr, "cleaning up %s objectn", s); }
};
Foo f("global");
int main() {
Foo g("local");
exit(0);
}
Produces this output:
cleaning up global object
Live on Godbolt
For any who might wonder about why this is written the way it is/how it works:
- Used
fprintf
instead ofstd::cerr
because whenf
is being destroyed, we don’t know whetherstd::cerr
still exists or not. - All string literals have static storage duration, so when
f
andg
are destroyed, the string literals they attempt to print do both still exist (even though it might sort of seem like the one used byg
might be destroyed upon exit frommain
).