I noticed that the FreeBSD code in /bin
and /usr/bin
have some fix to use exit
instead of return
, what does that mean?
All I have in my thought is that the return
statement may cause vfork(2)
to corrupt the stack frame, is that the only reason for this? If that was true, then why just a portion of the commands in /bin
and /usr/bin
got fixes, not all of them?
According to 5.1.2.2.3p1
If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument
This rules out your corrupt the stack frame theory; return 0;
is functionally identical to exit(0);
for conforming C implementations (at least for non-recursive main
entry points).
I would suggest that this change was merely stylistic, or perhaps guided by ignorance. Another possibility is that the author has the desire to transform main
into a recursive function (or main
has already been turned into a recursive function; idk, I just did a quick grep and it doesn't seem immediately recursive). Finally, as the last grim alternative, perhaps the C implementation that FreeBSD uses is non-conforming (I sure hope not!)...
edit: It just occurred to me by reading through this answer that this could have been a work-around for a compiler bug, but alas I checked the source code for usage of atexit
and could find no reason to pursue this line of reasoning any further.
Let's see if I can amalgamate the various links provided by others into an appropriate answer.
As far as the C language is concerned, there is no difference.
A call to exit()
does
atexit()
;tmpfile()
;A return <n>
from main is equivalent to exit( <n> )
.
Some flawed static code analyzers think different.
As far as the C language is concerned, memory allocated by main()
and not free()
d is leaked. Unix cleans up at process termination, but not all operating systems do (!).
Apparently, some static code analyzers consider memory still allocated at the point of exit()
to be not leaked (while they do for return
from main()
), which is why that commit was made (to get rid of the warning).
This is a workaround for a bug in the code analyzer.
As far as the C++ language is concerned, there is a lot of difference.
When you return
from main()
, you are leaving the scope of the function, which means local objects get destroyed.
Since C++ programmers enjoy the benefits of deterministic destruction (as opposed to e.g. Java which might or might not execute your destructor even on VM termination...), they tend to make their destructors do more than just freeing memory. Network connections, temporary files, terminal windows locked by ncurses
, all that kind of goodness, which C programmers would have to care for manually or use atexit()
for.
When you call std::exit()
from main()
, that function directly turns over control to the runtime. The main()
function never returns, the process gets terminated without calling the destructors of main()
-local objects.
Moreover, while std::exit()
is defined to flush and close the C output streams, there is no such provision for the C++ output streams.
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