2

I am writing a program where depending on input values, the code will terminate. That led me to think of the best way to implement this generally. I can easily come up with two examples:

if (bad_value) {
    clean_up();
    exit(1);
}

and something like this

try
    myFunc();
catch myException {
    clean_up();
    exit(1);
}

int myFunc() {
    if (badValue) throw myException;
    ...
}

The first code block seems much cleaner so I wonder why you would want to ever use exceptions? I guess this is really a battle of c vs c++.

theEpsilon
  • 1,800
  • 17
  • 30
  • 2
    I will go out on a limb and say never. There used to be a rule in writing operating systems that there should only be one HALT instruction in the entire thing. Same with applications IMHO. – user207421 Sep 29 '19 at 03:27
  • 1
    I once maintained a program made up of many thousands of lines of code where the previous developer thought it would be a good idea for a linked list to just `exit` the entire program if it got accessed out of bounds. So from the end-user's perspective the application would just randomly shutdown. That was not fun to figure out. – TheUndeadFish Sep 29 '19 at 04:32
  • [Why is using exit() considered bad?](https://stackoverflow.com/questions/25141737/) – Remy Lebeau Sep 29 '19 at 04:41

4 Answers4

3

Calling exit() is fine if you're writing application code, but if you're writing library code it is not good, because exit() forces the whole application to terminate when maybe the library code failure isn't that important and the application would rather continue.

Note you should call exit(EXIT_FAILURE) to tell the calling process that your program failed. If you throw an exception and do not catch it, that will also suffice.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
2

You're right, it's very much a matter of C style vs. C++ style.

The C idiom of passing a pass/fail flag means you have to explicitly check for an error every place it might occur. And if that flag needs to be passed further up the call stack, every function must allow for it. It can get unwieldy very quickly.

Calling exit means the low level code is making an unrevokable decision on how to handle the error. Often that's not appropriate. For example if you fail to open a file, maybe you can just put out a message to indicate that to the user and run without it.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
2

exit() is fine for small programs. For larger programs, there are several problems with it. First, not all errors should terminate a program - often it can recover.

The 2nd problem: even if you want to terminate, it is difficult to write a single clean_up() function that would take care of all resources allocated in various parts of the program. This what RAII in C++ is for. exit() is incompatible with RAII as it does not call destructors, except for global or static objects.

The 3rd problem: at the point of error detection, you often cannot construct an error message meaningful to the end user, but it is possible to construct such error message when an exception is caught.

Usually, the dilemma is different: the alternative to exceptions is using return codes to indicate errors. There are multiple trade-offs between exceptions and return codes, and hundreds of articles are devoted to this topic. It is too large to analyze within this answer.

Eugene
  • 6,194
  • 1
  • 20
  • 31
  • I think part of @JohnZwinck's answer should be put in here: "Calling exit() is fine if you're writing application code, but if you're writing library code it is not good, because exit() forces the whole application to terminate when maybe the library code failure isn't that important and the application would rather continue." – theEpsilon May 07 '20 at 20:41
1

You should not use exit(). To avoid calling all destructors, you should use std::quick_exit().

All exceptions should be handled at the top level of your code not to forget logging or some recover process.

yumetodo
  • 1,147
  • 7
  • 19