During development, when certain code paths must be prevented from the reach of control flow, you may use assert(0)
to indicate that such a condition is erroneous:
switch (color) {
case COLOR_RED:
case COLOR_GREEN:
case COLOR_BLUE:
break;
default:
assert(0);
}
Whenever the argument of the assert()
macro evaluates false, the macro will write diagnostic information to the standard error stream and then abort the program. This information includes the file and line number of the assert()
statement and can be very helpful in debugging. Asserts can be disabled by defining the macro NDEBUG
.
Another way to terminate a program when an error occurs are with the standard library functions exit
, quick_exit
or abort
. exit
and quick_exit
take an argument that can be passed back to your environment. abort()
(and thus assert
) can be a really severe termination of your program, and certain cleanups that would otherwise be performed at the end of the execution, may not be performed.
The primary advantage of assert()
is that it automatically prints debugging information. Calling abort()
has the advantage that it cannot be disabled like an assert, but it may not cause any debugging information to be displayed. In some situations, using both constructs together may be beneficial:
if (color == COLOR_RED || color == COLOR_GREEN) {
...
} else if (color == COLOR_BLUE) {
...
} else {
assert(0), abort();
}
When asserts are enabled, the assert()
call will print debug information and terminate the program. Execution never reaches the abort()
call. When asserts are disabled, the assert()
call does nothing and abort()
is called. This ensures that the program always terminates for this error condition; enabling and disabling asserts only effects whether or not debug output is printed.
You should never leave such an assert
in production code, because the debug information is not helpful for end users and because abort
is generally a much too severe termination that inhibit cleanup handlers that are installed for exit
or quick_exit
to run.