Error handling is a critical part of writing robust C programs. Unlike higher-level languages like Java or Python, C does not have built-in exception handling mechanisms (like try-catch blocks). Instead, C relies on return values, the errno variable, and specific functions to handle errors gracefully.
Understanding how to manage errors is essential for developing secure, stable applications that can handle unexpected situations without crashing.
The most common way to indicate an error in C is through the return value of a function. By convention, functions that successfully execute return 0, while a non-zero value (often -1 or NULL) indicates that an error has occurred.
#include <stdio.h>// Function returns -1 on error int divide(int a, int b, int *result) { if (b == 0) { return -1; // Error: Division by zero } *result = a / b; return 0; // Success }
int main() { int res; if (divide(10, 0, &res) == -1) { printf("Error: Cannot divide by zero!\n"); } else { printf("Result: %d\n", res); } return 0; }
errnoWhen a standard C library function fails, it often sets a global variable called errno (error number) to indicate what went wrong. To use errno, you must include the <errno.h> header file.
The value of errno is initially set to 0. It is modified by system calls and standard library functions when an error occurs.
Pro Tip: Always reset errno = 0; before calling a library function if you plan to check its value afterward, as successful calls do not clear previous error codes.
perror() and strerror() FunctionsWhile errno gives you an integer code, it is not very human-readable. C provides two functions to translate these codes into meaningful text:
perror(): Prints a descriptive error message directly to the standard error output (stderr).strerror(): Returns a pointer to the textual representation of the current errno value. It is defined in <string.h>.#include <stdio.h> #include <errno.h> #include <string.h>int main() { FILE *file = fopen("nonexistent_file.txt", "r"); if (file == NULL) { // Using perror to print the error perror("Error opening file"); // Using strerror to get the string representation printf("Detailed error: %s\n", strerror(errno)); } else { fclose(file); } return 0; }
To ensure your C code is production-ready, follow these best practices:
malloc), file handling (fopen), or input reading (scanf) will succeed.#define or enum) so other developers understand exactly what failed.When your main() function finishes, it returns an integer to the operating system. Standard practice is to return 0 for success and EXIT_FAILURE (defined in <stdlib.h>) for critical errors.
#include <stdio.h> #include <stdlib.h>int main() { int *ptr = malloc(100 * sizeof(int)); if (ptr == NULL) { fprintf(stderr, "Memory allocation failed!\n"); exit(EXIT_FAILURE); // Immediately terminate the program with an error status } free(ptr); return EXIT_SUCCESS; // Successful termination }
Which header file must be included to use the errno global variable?