Is it well-defined behaviour to exit the program before main? - c++

It's definitely possible to execute code before main is called, as seen by many examples in this question.
However, what if in that pre-main code, the program is told to exit via std::exit or std::abort? Since main is defined as the start of a program, what consequences are there from exiting before the start?
Upon printing something in each section, I get the following results:
Format:
Section: output
Main: main
Init (called before main): init
Exit (set up with std::atexit inside Init): exiting
Sample runs:
Init called without exiting:
init
main
returns 0
Init calls std::exit(0):
init
returns 0
Init calls std::abort:
init
crashes and returns 3 on Windows with GCC 4.7.2
crashes and brings up the usual box with VS11
returns 0 on LiveWorkSpace
Init sets handler and calls std::exit(0):
init
exiting
returns 0
Init sets handler and calls std::abort:
init
same deal as without the handler
While searching, I saw this question: Is there any way a C/C++ program can crash before main()?. However, it doesn't answer what I want to know: Is any of this behaviour, calling std::exit or std::abort before main, well-defined? Is any of this undefined behaviour?

The short answer is: there are (almost) no consequences. Some destructors may not be called if you unexpectedly call exit, but that's pretty much it.
Generally, not calling destructors is not the cleanest possible way, but then again the end result will be the same.
When a process terminates (via exit or abort or simply by segfaulting, or another reason), handles (kernel objects, files, etc.) are closed, and the memory associated with the program's address space is reclaimed by the operating system.
There is not much else to it either, because when you call exit or abort, you're basically requesting that the program terminates (these functions never return!) so you really can't expect anything to happen thereafter.
Note that registering a function like Init to be called before main is non-standard stuff, but you can get the same effect by having a constructor in a global.

Related

GLFW how to ensure glfwTerminate is called when the program exits?

In GLFW documentation it is written that glfwTerminate will
This will destroy any remaining window, monitor and cursor objects, restore any modified gamma ramps, re-enable the screensaver if it had been disabled and free any other resources allocated by GLFW.
and that one should call it before terminating the program. From my understanding that means, that if this function is not called the operating system doesn't have to re-enable the screensaver or restore modified gamma ramps, which is bad. How do I ensure that it is called regardless of how the program ends?
It's possible to use std::atexit to ensure it is called at the end if the program is exited via the exit command or by returning from the main function. It is also possible to do that making an object with a destructor in the main function that terminates when it is destroyed. The problem is what to do when the program ends with a signal. It's not possible to just register a function using std::signal, because glfwTerminate calls standard library functions other than the ones listed in https://en.cppreference.com/w/cpp/utility/program/signal which the site says is undefined behavior.
How do I ensure the program calls glfwTerminate? Or is it just not possible? And do I understand it correctly that without it the program can leave a modified gamma ramp after getting a signal? And are there any other ways the program can stop without calling the function?
There is no guarantee that the program will call glfwTerminate in case of segfaults or other undefined errors, so it is better to handle all errors before you decide to close it. So, recommendation is calling before the program terminates to restore the modified gamma ramps and re-enable the screensave.

How does exit(EXITT_FAILURE) work in both c and c++?

I used exit(EXIT_FAILURE) in a precise function which is not the main one, but after its execution nothing is executed in the main function.
I really wanna know why ?
Thanks a lot in advance.
In order to understand how exit works it helps to understand how program termination upon returning from main works.
When the program returns from main it returns to a piece of helper code in the C or C++ runtime. That piece performs some cleanup and then calls the _exit system call with the return value of main. The kernel will stop execution of the process at that point.
The exit function has similar behavior, it performs the same cleanup as the helper code from the C and C++ runtime does when returned from main, then calls the _exit system call. It's this last call to the _exit system call that prevents execution of anything else (in main or otherwise) after calling of exit.

main: return 0 hangs, exit 0 closes. How to debug?

I have a program that spawns three threads, does some communication between them, then closes them. The main thread waits for the last thread to close and then calls return 0.
But for some strange reason my program does not close but hangs when exiting with return 0, it closes fine with exit(0) however. I have already checked that the threads are really closed, I even forced them to close by issuing pthread_kill(pid, 0). I also tried valgrind to look for leaking memory.
As far as I understand the only thing exit() is not doing is calling the destructors of locally scoped non-static objects, but neither is there one in my main function nor would that explain why it hangs.
What is causing that behavior? How could I debug this?
code:
main.cpp: http://pastebin.com/7aN9KA6T
publisher.hpp: http://pastebin.com/Vhz1FKau
publisher.cpp: http://pastebin.com/09nh5YBs
boxoffice.hpp: http://pastebin.com/kaEbgNMJ
boxoffice.cpp: http://pastebin.com/wafaVcGV
You need to join each of your threads before returning.
bo_thread.join();
pub_thread.join();
sub_thread.join();
Also, pthread_kill(pid, 0) in the way you're using it has two issues.
It takes a pthread_t type, not a pid. This can be accessed through boost::thread::native_handle
Calling it doesn't actually 'kill' the thread. What it does depends on the second argument. With 0, it will just check if they're running. See the man page here: http://man7.org/linux/man-pages/man3/pthread_kill.3.html

How to exit a program with mixed C/C++ cleanly

I'm interfacing a C program (main() is in C) with C++. At some points in my code I want to stop execution of the program. Now I'd like to know, how can I do this cleanly?
At the moment I call std::terminate() but more out of a lack of better ideas. The main thing that bugs me isn't even that I'm not freeing the memory (because it's freed anyway on program termination, right?) but that the MSVS Just-in-time Debugger pops up and I get an ugly error message about terminating the runtime in an unusual way.
EDIT: As this has caused confusion: Returning from main() with return 0 is not possible in this case.
If you concern about cleaning up and invoking destuctors then
exit(EXIT_SUCCESS); // or EXIT_FAILURE
is the best choice between exit, terminate and abort.
Function exit calls descructors and cleans up the automatic storage objects (The object which declared in the global scope). It also calls the functions passed to atexit.
Function abort is useful for abnormal exits and will not clean up anything. It doesn't call the functions passed to atexit.
Function terminate does not exist in C. It's useful when you have an exception and you can't handle it but finishing the program.
main function is where it starts, main function is where it should end usually. If you use return 0; it indicates succesful exit.
int main(void) {
//init
//do stuff
//deinit
return 0; // bye bye
}
You could also use exit(0);, but if your exit points are scattered all over the place it makes things harder to debug.

Exiting from C++ Console Program

I currently have a program which has the following basic structure
main function
-- displays menu options to user
-- validates user input by passing it to a second function (input_validator)
-- if user selects option 1, run function 1, etc
function1,2,3,etc
-- input is requested from user and then validated by input_validator
-- if input_validator returns true, we know input is good
Here is my problem. I want to allow the user to quit at any point within the program by typing '0'. I planned on doing this with some basic code in input_validator (if input = 0, etc).
This would appear to be simple, but I have been told that using quit() will result in some resources never been released / etc. I cannot simply do a 'break' either -- it will result in my program simply returning to the main function.
Any ideas?
One possibility would be to do it by throwing an exception that you catch in main, and when you catch it, you exit the program. The good point of throwing an exception is that it lets destructors run to clean up objects that have been created, which won't happen if you exit directly from elsewhere (e.g., by using exit()).
exit()
Terminates the process normally,
performing the regular cleanup for
terminating processes.
First, all functions registered by
calls to atexit are executed in the
reverse order of their registration.
Then, all streams are closed and the
temporary files deleted, and finally
the control is returned to the host
environment.
This hasn't been true for any kind of mainstream operating system for a long time. The OS ensures that all kernel resources are released, even if the program didn't explicitly do so. Calling abort() or exit() from anywhere in your code is fine.
exit(int exitCode) - defined in stdlib.h / cstdlib - you'd probably want to exit(0); // normal termintation.
exit() will not call your destructors, so you might want to consider using an exception handler instead.
If you have things like open but unflushed files, the OS will close the file handles, but won't flush any unwritten data.
You have to design your menu system so that a status can be passed back to the previous method, unwinding until code in the main function is executed. Similar issues apply to back or previous screen buttons.
Taking a step back and looking at the Big Picture, the unwinding technique looks very similar to C++ exception handling strategy. I suggest using exceptions for cases that don't follow the normal flow of execution, such as main menu, and previous menu.
Try it out.