Hacker News new | ask | show | jobs
by superflyguy 2764 days ago
I've seen and use that. It's perfectly readable once you understand it's not a loop. It's handy on c, where you can't try...throw (or don't want to in c++) where you want to do a few things which you want to treat in a transaction-like manner. You would return success from the last line in the do loop and handle errors outside the loop. It's not just about mindlessly avoiding goto; it's about writing clean structured code.
3 comments

The problem is trying to understand that it’s not a loop. The first line of the block says “this is a loop”. The last line of the block says “this isnt’t a loop.”

The code is, if not outright lying, at least misdirecting.

You could always add a comment "this is not a loop" if you find it puzzling that the language allows you to loop zero times.
This is wrong in so many ways. First, I know the language. I’ve been doing this for almost 50 years. This isn’t a question of what the language allows but what the coder is trying to do.

Second, experience has taught me that code and comments often don’t agree. Too, if you have to comment that a loop really isn’t a loop then this is an indication that something is wrong.

Third, it isn’t a loop: while(false) never loops. That’s the point. Having to use a forward reference to understand the beginning of something is bad practice.

Fourth, this construct is almost always a sloppy way to prevent if-else creep. The code is invariably improved by a) not lying about the loop and b) refactoring.

In what sense is this any more clean or structured than a goto? It is literally a goto to an anonymous label, nothing else.
It's more clean in the way breaking or continuing from for loops and switch statements are. Or don't you approve of those either?
No, it's not more clean in the way those are. If you already have a loop, use break or continue. If you don't, it isn't "more clean" to introduce a pseudo-loop just so you can use break.
I'll grant that it would be handy to have a syntactic feature that would be equivalent to "break", but would apply to the current enclosing block. Basically like "return", but block-scoped - which is basically what this is, except for the whole intent/readability issue. I also like languages that let you do labelled "break" and "continue" out of the loop, rather than forcing you to put the label after the loop - IMO labeling the loop itself is more logical.

But we should be cognizant that those features are still extremely close to a naked goto in terms of the ability to reason about the code - it's just a sprinkling of syntactic sugar on top. So if goto is unequivocally bad, then e.g. early returns are also bad for all the same reasons. Conversely, if those features are fine when used in moderation or in well-established patterns (like "if (error) return") - which I believe is the case - then so is a naked goto. It's the cognitive dissonance of people who use them heavily while insisting that goto is absolutely evil, no exceptions, that irks me.

> - which I believe is the case - then so is a naked goto. It's the cognitive dissonance of people who use them heavily while insisting that goto is absolutely evil, no exceptions, that irks me.

Sounds like we are in agreement then.

The solution to this is an Error label after returning success and a "goto Error" in case of failure. The pseudo- loop plus break is not cleaner in any sense - its only purpose is to avoid typing "goto."