I'm thinking about a unified error handling interface.
I've come to conclusion that the errno global variable style isn't so bad, and decided to implement an improved version of it: every function called sets an error code to a global error variable through the get/set functions.
The difference with the errno pattern is that the code is set even if there's no actual error (ERR_OK enum value), so we get a status of an operation after each function call. This allows us to not reserve a special "error" return value. The global error variable is of thread local storage type.
What pitfalls could be met with such approach?
err.h:
#ifndef ERR_H
#define ERR_H
enum err {
ERR_OK
ERR_SOME,
};
void err_set(enum err e);
int err_get(void);
#define ERR (err_get() != ERR_OK)
#endif /* ERR_H */
err.c:
#include "err.h"
_Thread_local static int error;
void err_set(enum err e) {
error = e;
}
int err_get(void) {
return error;
}
main.c:
#include <stdio.h>
#include "err.h"
static size_t get_size(void *arg) {
if (!arg) {
err_set(ERR_SOME);
return 0;
}
err_set(ERR_OK);
return sizeof(*arg);
}
int main(void) {
void *bad = NULL;
size_t size = get_size(bad);
if (ERR) {
printf("Bad pointer!\n");
return 1;
}
printf("size == %zu\n", size);
return 0;
}