Error Handling in C with the 'OR' Macro December 2022 I made this macro to make error handling code more readable. #define OR ? (errno = 0) : (errno = errno ? errno : -1); if (errno) Be sure to `#include <errno.h>` Usage Evaluate expression1, if equal to zero then set errno to 0 and execute statement1. Otherwise set errno to -1. expression1 OR statement1 Example Usage Here is a simple example that catches a memory error. int main(int argc, char **argv) { char *memory; (memory = malloc(10000)) OR goto memory_error; return 0; memory_error: perror("failed to allocate memory"); return 1; } The two following code extracts show the same function except that the first uses the OR macro and the second does not. This demonstrates how much more readable using the OR macro is. /* Error handling with 'OR' Macro. */ int read_font_file(const char *fname, struct font_info *info) { int ret = 0; long size; FILE *file = NULL; char *ttf = NULL; (file = fopen(fname, "r")) OR goto file_error; fseek(file, 0, SEEK_END) == 0 OR goto file_error; (size = ftell(file)) >= 0 OR goto file_error; fseek(file, 0, SEEK_SET) == 0 OR goto file_error; (ttf = malloc(size)) OR goto allocation_error; fread(ttf, 1, size, file) == size OR goto file_error; read_ttf(ttf, size, info) == 0 OR goto ttf_error; cleanup: free(ttf); if (file != NULL) fclose(file); return ret; file_error: fprintf(stderr, "file error in '%s': %s\n", fname, strerror(errno)); ret = 1; goto cleanup; allocation_error: perror("failed to allocate memory"); ret = 1; goto cleanup; ttf_error: fprintf(stderr, "failed to parse ttf '%s'\n", fname); ret = 1; goto cleanup; } /* Error Handling with IF statement. */ int read_font_file(const char *fname, struct font_info *info) { int ret = 0; long size; FILE *file = NULL; char *ttf = NULL; file = fopen(fname, "r"); if (file == NULL) { char *err = strerror(errno); fprintf(stderr, "failed to open font file '%s': %s\n", fname, err); ret = 1; goto cleanup; } errno = 0; fseek(file, 0, SEEK_END); size = ftell(file); fseek(file, 0, SEEK_SET); if (errno) { perror("failed to get length of file"); ret = 1; goto cleanup; } ttf = malloc(size); if (ttf == NULL) { perror("malloc failed"); ret = 1; goto cleanup; } if (fread(ttf, 1, size, file) != size) { fprintf(stderr, "failed to read all bytes from file\n"); ret = 1; goto cleanup; } if (read_ttf(ttf, size, info) != 0) { fprintf(stderr, "failed to parse ttf\n"); ret = 1; goto cleanup; } cleanup: free(ttf); if (file != NULL) fclose(file); return ret; }