Consider this function:
int get_result(int *result) {
int err = 0;
int number = 0;
if (result == NULL) {
printf("error: null input\n");
return -1;
}
err = get_number(&number);
if (err != 0) {
printf("error calling get_number: err = %d\n", err);
return err;
}
err = calculate_result(number, result);
if (err != 0) {
printf("error calling get_result: err = %d\n", err);
return err;
}
return err;
}
The real work in this function requires only 3 lines (declare number variable, call get_number(), then call calculate_result()). However, the error checking/handling code bloats this function to 17 lines (give or take, depending on how you count the lines).
At a larger scale, with many calls, and multiple error checks, we bloat the function entirely and make it unreadable and very hard to understand.
What are ways to get around this bloating in C code and maintain readability of the core operation of a function (without sacrificing essential error handling code)?
errno
as a typename? – Velamenc
is like this. actually all languages are like this, you can argue in java you expand a easy call to a try-catch block too. so, you code what you need. – Reptant#define SAFE_CALL(expr) { errno err = expr; if (err != 0) return err; }
. this wouldn't be too bad if you restrict such usage in your code within a reasonable scope. – Reptantgoto
might help. See https://mcmap.net/q/110326/-good-c-style-when-checking-lots-of-return-values – Photoconductivityerrno_t
provided or not? if not, you shouldn't name your type in*_t
form since all of them are reserved according to standard. – Reptantint
for error codes is common practice in c, so glad you fixed that. – Relucentassert(result != NULL)
. – Caundra