Most examples of "good" breaks in this thread can be expressed cleaner without break.
@Pax Diablo
i agree with your premise ("do what increases readability"). i disagree with your conclusion ("breaks increase readability"). 'continue' increases readability by increasing statement locality and emphasizing linear execution. 'break' causes execution flow jumps and shatters loop encapsulation.
the loop you used as an example just begs to be refactored. At first glance, I would reasonably presume that when the loop is finished, x==0 and all indexes 0 < i < Xinitial have been processed. To realize that this is not the case, I would have to parse the entire loop.
@Jay Bazuzi, you said this was good:
foreach (var x in MySequence)
if (SomeCritera(x))
break;
this is equivalent and more elegant:
var x;
while (valid(x) and not SomeCriteria(x))
next x;
@Quarrelsome, you commented:
foreach(Thing stuff in things)
{
if(stuff.Id == thingImLookingFor) { // do stuff break; }
}
this is more readable:
var thing;
while (valid(x) and not IsThingImLookingFor(x)) next x;
do stuff
@Rob Walker, you said this was the best:
for (ListIt it = ...; it.Valid(); it++)
{
if (it.Curr() == ...)
{
.. process ...
break;
}
}
how about this (exact same paradigm as the above two refactorings)
ListIt it = ...;
while (it.Valid() && it.Curr() != ...) it++;
Process(it);
@Cervo - one of your examples is weak, but the other example seems ok - the one necessary use of 'break' so far in this thread.
while list.hasItem()
item = list.next()
if check fails continue
.....
if checkn fails continue
do some stuff
if end of list item checks break
end while
i don't understand exactly what you mean by if end of list item checks break
, but it seems that it isn't even necessary - the loop would naturally finish because there are no more items. if you don't mean to loop until the list is empty, why not use if NOT end of list item checks
as your loop condition? no break, preserves loop encapsulation (the entire loop body could be factored into another function, with 'continue' mapped to early returns.
the one good use of 'break' in this thread that I can see
@Cervo - this is a good example.
currentValue = some function with arguments to get value
while (currentValue != badValue) {
do something with currentValue
currentValue = some function with arguments to get value
}
versus the better:
while (1) {
currentValue = some function with arguments to get value
if (currentValue == badValue)
break
do something with currentValue
}
I could only come up with this response, which is specific to a subset of languages, i think it's worse than your while(1).
while ( (input = getch()) != ‘\0’)
Process(input);