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.
Related
While working on a thread (fiber) scheduling class, I found myself writing a function that never returns:
// New thread, called on an empty stack
// (implementation details, exception handling etc omitted)
[[noreturn]] void scheduler::thread() noexcept
{
current_task->state = running;
current_task->run();
current_task->state = finished;
while (true) yield();
// can't return, since the stack contains no return address.
}
This function is never directly called (by thread();). It is "called" only by a jmp from assembly code, right after switching to a new context, so there is no way for it to "return" anywhere. The call to yield(), at the end, checks for state == finished and removes this thread from the thread queue.
Would this be a valid use of the [[noreturn]] attribute? And if so, would it help in any way?
edit: Not a duplicate. I understand what the attribute is normally used for. My question is, would it do anything in this specific case?
I'd say that it is valid but pointless.
It's valid because the function does not return. The contract cannot be broken.
It's pointless because the function is never called from C++ code. So no caller can make use of the fact that the function does not return because there is no caller. And at the point of definition of the function, the compiler should not require your assistance to determine that code following the while statement is dead, including a function postlude if any.
Well, the jmp entering the function is a bit weird, but to answer your Question is
"Most likely no".
Why most likely ? Because I don't believe you understand the idea of no return OR you are stating your use case wrongfully.
1st of all the function is never entered (or so you are stating) which means that by default is not a no-return (dead code could be removed by the compiler).
But let's consider that you are actually calling the function without realizing it (via that "JMP").
The idea of a no-return function is to never reach the end of scope (or not in a normal way at least). Meaning that either the whole Program is terminated within the function OR an error is thrown (meaning that the function won't pop the stack in a normal way). std::terminate is a good example of such a function. If you call it within your function, then your function becomes no return.
In your case, you are checking if the thread is finished.
If you are in a scenario where you are murdering the thread through suicide , and this is the function which is checking for the thread completion , and you call this function from the thread itself (suicide, which I highly doubt, since the thread will become blocked by the while and never finish), and you are forcing the thread to exit abruptly (OS Specific how to do that) then yes the function is indeed a no return because the execution on the stack won't be finished.
Needless to say, if you're in the above scenario you have HUGE problems with your program.
Most likely you are calling this function from another thread, or you are exiting the thread normally, cases in which the function won't be a no-return.
We have a large Fortran application which calls many C++ modules. I am trying to use the C++ objects' destructors to free resources and close files, but it seems they are not being called when the Fortran program exits.
The Fortran program exits using the STOP command.
Do I need to use a different Fortran command to exit, or call the C++ exit(0) command from Fortran?
To get proper construction/destruction, you just about need the entry point to be on the C++ side.
At least offhand, the simplest approach I can think of that seems at all likely to work would be something like this:
set up main in C++, and have it as the entry point.
move your current Fortran entry point into a function.
call that function from main
write a small function in C++ named something like do_stop() that just throws an exception
in your Fortran, replace STOP with calls to do_stop().
You can either leave the exception uncaught, or have a try/catch in main, which can give a slightly more graceful exit (display an error message of your choice instead of something written by the library author saying your program has an error).
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.
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.
Is it guaranteed that a function registered with atexit will ALWAYS be called upon normal program termination? (I encounterd a scenario in FreeBSD where a function that I register with atexit never gets called, even when the program terminates normally).
No. First, the function will not be called if atexit returns a non-0 value. Secondly, it won't be called if a function registered before it doesn't return normally.
What do you call "normal termination"?
Unix and C99 have functions _Exit (both POSIX and C99) and _exit (only POSIX) which allow to terminate a program with whatever status you want and without running the atexit handlers. The other cases I know where they aren't run all clearly fail into the "abnormal termination" bucket.