3 ms·
I like the presentation of the three nexted loops. Maybe "break;" should become a shortform for a generalized "break(1);" (= break one level) if we want to avo
by jll29 5y ago
I like the presentation of the three nexted loops.
Maybe "break;" should become a shortform for a generalized "break(1);" (= break one level) if we want to avoid using goto.
Perhaps this can be implemented by combining a macro with setjmmp() and longjmp() from the standard C library, without requiring a compiler change.
- wruza 5y agoYep, some goto uses were ostracized without ever providing the alternative. In other languages breaking numerous loops is done by naming the one you want to control: outer: for () { for () { for () { break outer;
- jkcxn 5y agoIsn't it interesting that all of the examples in the original article can be replaced with a labeled break of arbitrary blocks? Even replacing the continue statement. Solving the problems of goto and keeping the behaviour. Not sure why more languages don't have this
- OskarS 5y agoThis is much more confusing to me than just using a goto. From your example, it's not immediately clear at all to me if you're breaking out of outer, or if you're breaking TO outer. You can figure it out with this simple example, but it's way more confusing than it needs to be. And importantly: way more confusing than just using goto. Given that break and continue are just gussied up gotos anyway, just put the label where you wanna go and goto it. I think it's one of the few perfectly valid uses goto.
- Jtsummers 5y agoThere is no confusion if you're already familiar with the anonymous break: // find in a loop for (a : array) { if (a == target) { print("Found it"); break; } } This breaks the loop. A named break is no different except that it names the loop that will be broken out of: find: for (a : array) { if (a == target) { print("Found it"); break find; } } Exactly the same as the previous, but we've named the loop for some reason. If you can understand this, then the case of named breaks (or named continues) with multiple nested loops are comprehensible with some effort spent writing or reading illustrative examples like the above. Why would it do anything else? A break is a break, it terminates the loop. To re-enter that loop would be a continue, not a break. > Given that break and continue are just gussied up gotos anyway, just put the label where you wanna go and goto it. I think it's one of the few perfectly valid uses goto. The reason not to do this is that goto's can (as illustrated in the submitted article) lead to some erroneous behavior that is harder or impossible to achieve with more structured equivalents (like named breaks and continues). Like, your goto can jump past variable initializations and get you undefined behavior. Using the structured equivalent of: for (a : array) { if (a == target) { print ("Found it"); goto found_it; } } found_it: ... Removes those potential errors from the system. That, of course, doesn't mean that goto should be forbidden entirely (plenty of examples in this discussion of where it's useful), or that something like the preceding wouldn't be useful in some circumstance. But if we follow the idea that you present ("break and continue are just gussied up gotos anyway") to its conclusion, we'd be back to the unstructured code that was Fortran and its contemporaries, because why should we have if, if-else, while, for, function calls, etc. when they're all just gussied up goto anyways?
- wruza 5y agoThe source of confusion is my generic naming. Name it “files_loop: for …” and “break/continue files_loop” will be obvious to a reader. Also do not forget that a label is not a distinct point in C, it is a part of a “labelled statement” [1], so you do not break to it, you break/continue/goto it. I think it's one of the few perfectly valid uses goto. I fully agree, but for 99% of our religious peers it is an NSFW taboo. [1] https://www.lysator.liu.se/c/ANSI-C-grammar-y.html#labeled-statement https://www.lysator.liu.se/c/ANSI-C-grammar-y.html#labeled-s...
- beej71 5y agoThe next version of C is likely going to have `break break` to break two levels. I'd have preferred `break label` or no change, but there we are.