You should never use EXIT_SUCCESS
or EXIT_FAILURE
outside of the context of a call to exit()
or the return value to main()
. The values of these integers are not specified by the standard, so you cannot write portable code if you assume that they are 0 or 1 respectively.
The standard does specify that exit(0)
and a return 0
from main()
behave the same way as exit(EXIT_SUCCESS)
and return EXIT_SUCCESS
, but these values are "special" in that they are to be interpreted in an implementation defined manner. That is, the actual value passed to the system may not be 0, and the constant value of EXIT_SUCCESS
is free to not be 0 if the implementation desires, so long as return 0
from main and return EXIT_SUCCESS
from main behave the same way.
If you use these values in your functions, your callers will have to compare against EXIT_SUCCESS
directly to determine if the function succeeded, which personally speaking I would find very inconvenient.
int MyFunction1 () { /* ... */ return EXIT_SUCCESS; }
int MyFunction2 () { /* ... */ return 0; }
// Portable:
if (MyFunction1 () == EXIT_SUCCESS) { ... }
if (MyFunction2 () == 0) { ... }
if (!MyFunction2 ()) { ... }
// Not portable:
if (MyFunction1 () == 0) { ... }
if (!MyFunction1 ()) { ... }
if (MyFunction2 () == EXIT_SUCCESS) { ... }
The problem becomes more obvious with EXIT_FAILURE
:
int MyFunction1 () { /*... */ return EXIT_FAILURE; }
// Not portable
if (MyFunction1 ()) { ... }
if (MyFunction1 () == 1) { ... }
// The only way to make this portable.
if (MyFunction1 () == EXIT_FAILURE) { ... }