In C, C++ and C# when using a condition inside a function or loop statement it\'s possible to use a continue or return statement as early as possible and g
1) Input or object state validation. Following code:
void function() {
if( condition ) {
//do some stuff
return;
}
//do other stuff
}
is good when the condition is some requirement for function to work. It's a stage of input validation or object state validation. It then feels right to use return immediately to emphasis, that function did not run at all.
2) Multistage processing. While/continue is good when the loop pops elements from some collection and processes them in multistage manner:
while(foo = bar.getNext()) {
if(foo.empty())
continue;
if(foo.alreadyProcessed())
continue;
// Can we take a shortcut?
if(foo.tryProcessThingsYourself())
continue;
int baz = foo.getBaz();
if(baz < 0) {
int qux = foo.getQux();
if(qux < 0) {
// Error - go to next element
continue;
}
}
// Finally -- do the actual processing
baz = baz * 2;
foo.setBaz(baz);
}
The example shows how natural it is to use continue in scenario when series of multistage processing is done, when each processing can be interrupted by various conditions in various places.
Notice: plinth posted real-life example, which follows what 2) says.
3) General rule. I use continue and return when it corresponds with fact that something has been interrupted. I use else, when the else is part of actual processing.
The glib answer is that it all depends.
My general feeling is that if condition
is a rare, guard (e.g. check for null) or error condition then I tend to use return
or continue
If it's an expected case then I tend to use your first approach.
Notice, however, that I said "tend". The boundary between these to conditions is vague and subject to change depending on the project and who I'm working with.
One possible maintenance issue is that if a function has multiple returns, then it is harder to stick a breakpoint or tracing at the return when debugging. This is only rarely an issue, but when you do miss a return point it's a pain. I don't think it matters so much for continue in loops, since the loop condition and the top of the loop are both still unique.
Aside from that: what everyone else says. Do what's most readable, which depends on the relative length, importance, and likelihood of "some stuff" and "other stuff". The shorter, more trivial, and more unlikely a case is, the less disturbing it is for it to have special-case control flow.
I usually prefer
while( loopCondition ) {
if( innerCondition ) {
DoStuff();
} else {
DoOtherStuff();
}
}
continue can be hard to follow if the length of DoStuff passed the 1-2 line threshold (and its fairly easy to miss the intention). This seems like a good opportunity to refactor the logic into some smaller methods.
It depends a little on how long the branches are. The use of return/continue that you describe is good if the initial if
check is short, and the body is long. If both if
and else
parts are long, I would extract them to separate functions.
I recommend reading Code Complete, it discusses things like this a lot.
The compiler will almost certainly generate the same code. Even if it didn't, the difference will be probably irrelevant. Hence, the relevant argument is certainly how people would read it.
Therefore the question is how similar "//do some stuff" and "do other stuff" are. If they are conceptually similar, use if/else. If they're conceptually different, use continue/return.