In C a typical way to simplify error checking and avoid deep nested if
is:
do
{
if (condition1) break;
/* 1. do something... */
if (condition2) break;
/* 2. do something else... */
if (condition3) break;
/* 3. do something else... */
} while(0);
/* Cleanup */
There are various opinion on this "idiom" (e.g. take a look at Do you consider this technique “BAD”?).
Possibly you should add a comment on the do
to make it clear to anyone what's happening.
You can often rewrite the code using a helper function and change the fake do-loop into:
void func(X *x, Y *y)
{
if (condition1) return;
/* 1. do something... */
if (condition2) return;
/* 2. do something else... */
if (condition3) return;
/* 3. do something else... */
}
/* ... */
X x;
Y y;
func(&x, &y);
/* Cleanup */
and it won't be considered a "bad practice" since it's more expected.
If you haven't the intermediate steps (1.
and 2.
) this is probably enough:
int stop = condition1 || condition2 || condition3;
if (!stop)
{
/* ... */
}
/* Cleanup */
goto
. It makes the intent of the code clear and is cleaner than camouflaging the control flow by any misguided attempt to cheat around using thegoto
statement. I really dislike the idea of blindly following “never do X” rules when X actually is the best (least bad) alternative in a given case. This particular pattern (goto cleanup;
) is actually quite idiomatic in C. – 5gon12eder Mar 24 '15 at 12:21goto
in C that concluded that this is the case where they're being used and that applications which cause spaghetti are relatively rare. – Blrfl Mar 24 '15 at 16:20goto
to implement a custom control structure. Go recognized this for what it is - a control structure - and added thedefer
statement to cover this (valid) use-case. – Riking Mar 24 '15 at 17:59