I had recently read in a book that using the break
statement in say e.g. for
loops is considered inelegant (although it is widely accepted for use in the switch
statement).
What is the reason for this "accusation"?
Should I use a break
statement in a for
loop, or should I use multiple conditions?
You'll have to ask the author of the book (which book?), since my ESP is on the fritz today[citation needed].
Sometimes[when?] it's said that, if you write lots of break
statements throughout your code body, then it's no longer easy to see the loop invariants and the control flow without performing a detailed program analysis.
But, realistically, a couple of break
statements inside conditional blocks isn't going to hurt anyone, and complicating loop conditionals is, IMO, more immediately prone to going horribly wrong.
The reasoning is that it's clearer to have the condition for continuing or exiting the loop in one place rather than scattered throughout the body of the loop.
This is like those who say goto
is bad because of a paper Djikstra wrote on the subject in the 60's. When used liberally, I would agree. But for instance, in a C-function, which doesn't have the benefit of C++'s exception handling using try
and catch
, the deliberate and intentional use of goto
can be very helpful in creating a self-contained clean-up section in case of an error return for a function that allocates memory using malloc()
. Without the goto
statement, you would have to place clean-up code at the end of every if
statement that detected an error. For instance, what looks better to you ... this:
int my_func()
{
int* a = malloc(10);
//... some code
if (some_error)
{
free(a);
return -1;
}
//... more code
if (some_other_error)
{
free(a);
return -1;
}
//... more code
if (another_error)
{
free(a);
return -1;
}
//... more code
free(a);
return 0;
}
or code that looks like this:
void my_func()
{
int* a = malloc(10);
//... some code
if (some_error)
goto return_error;
//... more code
if (some_other_error)
goto return_error;
//... more code
if (another_error)
goto return_error;
//... more code
normal_return:
free(a);
return 0;
return_error:
free(a);
return -1;
}
With the first example, every time you changed something, you would have to manage all the error returns in each of the if-statement blocks. The latter approach gives you a nice self-contained clean-up section. So the same is true with other arbitrary rules for syntax like "don't use break
in a loop" ... if it helps increase the code's maintainability, reliability, and readability, by all means use it.
It's a matter of style.
There would be people who say it breaks the flow of the loop ( Just like you shouldn't use multiple return statements in a method).
But a break
is very expressive. Properly placed breaks can be much more readable and maintainable than a loop condition that includes the state in which we should stop the loop (instead of the breaks).
I am not sure if it helps, but, Joaquín M López Muñoz addressed this question in his blog: http://bannalia.blogspot.com/2009/03/about-break-statements.html
Regards, &rzej
精彩评论