问题
I've recently come across this code:
do {
if ( ! checkSomething() )
break;
// some code
if ( ! checkSomeOtherThing() )
break;
// some other code
} while(false);
// some final code
The programmer that wrote it, wrote a comment along the lines of "cleaner control flow"
.
In my opinion, the original code could look better if its refactored into something else. But is there any truth in this statement ? Is this construct any good ?
回答1:
If you don't mind loops containing several break
statements, then the only problem here is that C (for obvious reasons) doesn't let you break out of a bare block, hence the "non-loop" which some unsuspecting future maintainer could mistake for a real loop.
The considerations, I think, are:
- if there are only two
break
points, what's so bad about twoif
statements? - if there are more than two break points then the indentation with
if
statements could get unpleasant, and this saves that, but then again is the function doing too much? And even if not, would it be better just to usegoto
and avoid the weirdness of a loop that doesn't loop?
Since you tag this language-agnostic, I used to use a macroised assembly language, with a block
... endblock
that you could break out of. This lead to reasonably nice code for checking necessary conditions, such as:
block
breakif str1 == null
breakif str2 == null
get some combined property of str1 and str2
breakif some other condition that stops us getting on with it
get on with it
endblock
Actually, it wasn't breakif str1 == null
, it was breakifeq.p str1, null
, or something like that, but I forget exactly what.
回答2:
I find this much easier to read, and it produces an identical result:
if ( checkSomething() )
{
// some code
if ( checkSomeOtherThing() )
{
// some other code
}
}
// some final code
I think do ... while
is normally hard to follow, but using it for something other than a loop is misleading at best.
回答3:
This is equivalent to a goto
.
In such situations, it is better to use a goto
than to use an ugly hack.
Changing it to use a goto
makes it much more readable:
if (!checkSomething())
goto Done;
// some code
if (!checkSomeOtherThing())
goto Done;
// some other code
Done: //some final code
回答4:
I've seen the do-while form adopted as a standard to which coders conformed. The advantage is that it communicates, and implements, that the loop will always be executed at least once. This helps isolate, with consistency, the situations where something different occurs, i.e. where the code in the loop is not executed.
This standard was adopted because the Warnier-Orr technique was being applied.
来源:https://stackoverflow.com/questions/4362145/does-the-construct-do-whilefalse-contribute-to-better-control-flow