The "break" instruction is really just bad, lazy coding practice.
That's an unjustifiably broad statement. I think you meant that using break to jump around willy-nilly through nested loops is bad, and sure, it is--spaghetti is spaghetti--but that is more about the structure of the program than the tool used to assemble it. There are plenty of situations where break provides the cleanest and easiest to read solution to a problem. Just like goto, it's a tool of the language, and it's up to the programmer to use it where it makes the most sense. You can just as easily create inscrutable spaghetti using tons of ifs to check different flags inside of loops where judicious use of break/continue would have done a much more elegant job. It all depends on the problem you're trying to solve.
Exactly. The "break and goto are bad" attitude is one of the leading "simple" (low-level or syntax level) reasons I see leading to spaghetti code. If you forbid a beginner from using proper tools, and instruct them to "work around", they indeed will. Instead of using clear and concise, self-explanatory command (such as break or continue, or to limited extent, goto) to describe exactly what the program does, in exactly the spot where it happens, a beginner is guided to believe they need to construct a "distributed" solution with a definition of a temporary variable of unclear, hard-to-descrive purpose (and hence, often illogical name) in one place, then assign to it in another place (or multiple places!), and compare it in a third place (or God forbid, in multiple places), and then analyze what can and may happen between the variable assignment and when it's tested the next time, and possibly write corner case logic for handling that.
And this would be, somehow magically, "good coding practice".
Guess what - it isn't. You don't define "good coding practices" by repeating ages old, disproved-to-death mantras. You do it by careful analysis and sound reasoning. Or you do it by the mantras if you have the authority and power to do so, but then you'll bear the consequences of having broken coding practices in your company or community.
This is one of the most typical litmus tests that show who are competent and who just blindly repeat "good practices" they were taught in school or by other incompetent instructors.
A good coding practice should never be a workaround to the "actual" tool people would like to use, motivated by the idea that being "lazy" is bad.
Laziness is
good. Simple and clear tools are good.
No one has never ever been able to reason why
break is bad using any actual argument that holds
any water.
In the situations where using break or continue is hard to follow due to too many levels (this happens, indeed), blindly changing it to some kind of "quit variable" setting and testing is often a recipe for an even worse disaster, since it might get
even more difficult to follow. A quick fix to make it
better is sometimes goto (which explicitly states
where the program flow will jump from and to, allowing and necessitating the destination to have a documenting label), but the
best solution is to restructure to remove excess levels, or blocks too long in a single function. I.e., divide into smaller functions.
I have almost never seen a badly used break instruction, and quite seldom, a badly used goto. Actually seeing that famous "goto spaghetti code" is almost nonexistent, as well. But teaching how you need to avoid them - and often suggesting ridiculously bad ways to work around them - all the freaking time
causes
really bad code, everyday, everywhere, and this is actually dangerous, unlike the mythical Goto Spaghetti Monster.