0

I'm writing a C program, and I'm curious about something. The program has several functions that return 1 on success and 0 on failure, and most are called by main() (though some are called by other functions). This is for an assignment, and if an error is caught I need to print the error to stderr using fprintf() and terminate the program.

What is the proper way to handle error termination? Should I allow the function to print to stderr, then return 1 back to main() then have main() actually terminate, or should the function itself handle error printing and program termination?

vaindil
  • 7,536
  • 21
  • 68
  • 127

2 Answers2

4

The C standard states:

5.1.2.2.3 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.

So it is perfectly valid, when you encounter a fatal error to do a exit(errcode);

Usueful to know: with atexit() you can specify a function (with no argument) that will be called by exit() (for example to clean up the mess). You can even define several such functions: they will be called in the reverse order of their registration.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • 1
    Depending on the kind of fatal error encountered, `exit` **might be inadvisable**. There's a reason for `_Exit` (or `abort`). – Deduplicator Feb 15 '15 at 23:26
  • @Deduplicator you are of course right. My answer was about return from `main()` vs. `exit()`. Of course in exceptional cases `abort()` or `_Exit()` could be advisable, but I'd say it's rather the exception than the rule. – Christophe Feb 15 '15 at 23:44
1

It depends on your needs. If a catastrophic error occurs, and you must exit in a hurry, you can call exit(). You can think of it as a "panic quit".

But good form mandates that you never exit(), and that instead you return from all function calls and let main() return. As a matter of fact, good form is to do that even if an error occurs if possible. exit() is only meant to be used in rare situations where you specifically want to prevent any other code from executing.

Consider, for example, what would happen if your professor wished to include the functions written by each student in a larger program and invoke them one by one. If one of the functions exits, the remaining students' functions would never run.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • 2
    Don't confuse `exit` (which calls `atexit`-handlers) with `_Exit`. – Deduplicator Feb 15 '15 at 23:22
  • The `exit()` function does an orderly shutdown, closing I/O streams and flushing pending output, and running functions registered with `atexit()`. `abort()` doesn't necessarily flush any pending output from the standard I/O streams, and doesn't run any functions registered with `atexit()`, and usually produces a core dump (as if the process were terminated with a SIGABRT signal). There are also the `_exit()` and `_Exit()` functions. In C11, there's also the `quick_exit()` function and corresponding `at_quick_exit()` function. – Jonathan Leffler Feb 15 '15 at 23:23
  • @JonathanLeffler thanks for the information, I see that's way too complicated, and probably of no interest to the OP, so I will just remove the part about `abort()` from my answer to keep things simple. – Mike Nakis Feb 15 '15 at 23:24
  • 1
    I don't recall ever seeing `exit()` called a "panic quit" before reading this answer. – Jonathan Leffler Feb 15 '15 at 23:27
  • @JonathanLeffler it is not unheard of, (http://stackoverflow.com/questions/2177597/inputs-for-improving-code-debuggability-apart-from-logs-and-error-codes) either in C or in other languages, (https://github.com/pingviini/mydotfiles/blob/master/install.sh) but in any case, I am rewording. – Mike Nakis Feb 15 '15 at 23:36
  • 1
    OK; that's why I put "I don't recall ever seeing", emphasizing my personal limitation…I think it is an unusual appellation — it is a perfectly ordinary way of terminating a program. 'Panic quit' operations are things like `_exit()` and `abort()`, in my book. _[…looking at your x-ref…]_ The author of the code created a function there called `panic()` which reports an error message and then invokes `exit()`. The panic is in the mind of the writer of the function; the `exit()` is still perfectly normal. Panic also has a specific meaning in the context of Unix (and Linux) kernels, for example. – Jonathan Leffler Feb 15 '15 at 23:41
  • 1
    The return to main() is not necessarily the only good form, otherwhise the standard would not have written that both are equivalent. The term "good form" refers to personal opinions. My personal experience is that for rare and very nested errors, its sometimes more effective to have a solid `exit()` rather than to design complex multilevel error returning. But these thoughts remain opinions and not facts. – Christophe Feb 15 '15 at 23:55