Error Handling in C Programming
Error handling in C is an essential aspect of writing reliable and maintainable code. Since C does not provide built-in exception handling like some higher-level languages, programmers must implement their own error-handling logic using standard tools such as return codes, errno, and assertions.
1. General Approach to Error Handling
In C, most functions signal errors through:
- Return values (e.g.,
NULLor-1) - Setting global variables like
errno - Manual checks with conditional statements
Always check the return value of library functions (e.g., memory allocation, file handling, system calls) to ensure that operations have completed successfully.
2. Using errno for Error Reporting
The C standard library defines errno in <errno.h>, a global integer variable that is set by system calls and some library functions to indicate what error occurred.
Key Points:
errnois not automatically reset to 0, so set it to 0 before calling a function if you want to check whether an error occurred.- After a failure,
errnocontains an error code (e.g.,ENOMEM,EINVAL,EIO). - You can use
perror()orstrerror()to print or interpret the value oferrno.
Useful Functions:
| Function | Description |
|---|---|
perror() |
Prints a human-readable error message to stderr |
strerror() |
Returns a string describing the error code |
Common errno Values:
| Macro | Meaning |
|---|---|
ENOMEM |
Not enough memory |
EINVAL |
Invalid argument |
EIO |
I/O error |
EPERM |
Operation not permitted |
ENOENT |
No such file or directory |
Best Practices with errno:
- Include
#include <errno.h>at the top of your program. - Set
errno = 0before making a call. - After the call, check if it failed (e.g., returned
NULL) and inspecterrno. - Print the error message using
perror()orstrerror(errno).
3. Using assert for Debugging
The assert macro is defined in <assert.h> and is used to perform sanity checks during development. It evaluates a condition, and if the condition is false, the program prints an error message and terminates.
Syntax:
assert(expression);
- If
expressionevaluates to false, the program terminates and displays the line number and file where the failure occurred. - Assertions are generally used to validate assumptions during development and testing.
- They can be disabled in release builds by defining
NDEBUGbefore including<assert.h>.
Best Use Cases for assert:
- Checking for null pointers.
- Validating preconditions and postconditions.
- Ensuring array indices are within bounds.
- Detecting logic errors during development.
4. Return Code Convention
C programs often follow these return conventions:
0for success- Non-zero for failure
This convention is followed in main() and other functions, helping external tools (shell scripts, compilers, etc.) detect whether a program executed successfully.
5. Summary Table
| Tool | Purpose | Best Used When |
|---|---|---|
errno |
Identify error from standard/library/system calls | When function may fail silently |
perror() |
Print error message | When you want detailed error output |
strerror() |
Convert error code to message | When you want to display/log messages |
assert() |
Terminate on logic failure | For debugging and catching logic errors |
Error handling in C may be manual, but it is powerful when done correctly. Proper use of errno and return values helps you write robust and predictable programs. assert helps catch mistakes early during development. By combining careful return value checking, diagnostic tools like errno, and assertions, we can ensure that your C programs behave reliably, even under unexpected circumstances.