What is considered best practice for aborting on errors in C?
In our code base we currently have a pattern using
#define CHECKERROR(code) if(code) { return code; }
but this leads to resources not being closed in code of the form
/* not actual code due to non-disclosure restrictions */
int somefunction() {
handle_t res1, res2;
int errorcode;
res1 = getResource();
res2 = getResource();
errorcode = action1(res1, res2);
CHECK(errorcode);
errorcode = action2(res1, res2);
CHECK(errorcode);
freeResource(res1);
freeResource(res2);
return errorcode;
}
I came across the pattern
/* initialize resources */
do {
/* ... */
errorcode = action();
if(errorcode) break;
/* ... */
} while(0);
/* cleanup resources */
return errorcode;
before in articles, but couldn't find any source discussing it now.
What is a good practice, that would be considered idiomatic to C? Does the do { } while(0); pattern qualify? Is there an idiomatic way to make it more clear, that it is not intended to be a loop, but a block with non-local exit?