It's a good practice (I believe) in C to handle errors like this:
int status = tree_climb(tree, ...);
if (status != 0) {
global_logger.message(2, "Cannot climb a tree %s", tree->name);
return EPIPE;
}
or, alternatively
forest_errno = tree_climb(tree, ...);
if (forest_errno != 0) {
goto exit;
}
exit:
if (tree) {
tree_dispose(tree);
}
if (forest) {
forest_dispose(forest);
}
return forest_errno;
The questions is:
What are the reasons not to use a preprocessor macro for this? I cannot remember seeing a lot of code like:
#define CHECK_OR_RETURN(contract, error_status, log_level, message_format, ...) \
if (!(contract)) { \
global_logger.message(log_level, message_format, ##__VA_ARGS__); \
return error_status; \
}
I see these reasons to use a macro:
- This will collapse 4 lines of code, 3 of which do nothing during normal flow of operation, into 1.
- Error handling, ideally, should not pollute the code for a normal flow.
I see these reasons not to use a macro:
- Macro will obtuse reading and debugging the code somewhat. Self-invented "magic" syntax can turn a familiar language into an incomprehensible one - sometimes, you just cannot parse a code without knowing a library specifics. Though, on a large scale, a code 3 times shorter is 9 times more readable.
- In C++, we could use exceptions. I would rather not use non-checked exceptions, but it's not in the scope of my question.
- Some people just don't care for the code length.
So why don't people do this all the time?