8

If in code there are many if-clauses and execution of code is not sensible on a previous error, is it OK to use a one-cycles loop for this? Simply for being able to exit the block with a break? Like this:

do {
    //..code
    if (error1) break;
    //..code
    if (errorN) break;
    //do finally something when no errors before
} while (false);
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Valentin H
  • 7,240
  • 12
  • 61
  • 111

2 Answers2

7

Yes, this is idiomatic, even if, perhaps, it was not the intended use for a do while loop. The source code for the linux kernel exploits this.

There's nothing unclear about it: while(false) does exactly what is says on the tin.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 1
    Thank you for mentioning linux kernel! – Valentin H Sep 19 '16 at 11:52
  • What's the advantage of such a technique instead of checking for `! error` and executing the code inside of an `if` block ? – Thomas W. Sep 19 '16 at 11:55
  • 2
    Well then, you have to have a suitable `error` around in scope, and `if` doesn't have a `break`. – Bathsheba Sep 19 '16 at 11:56
  • 1
    @Thomas If there are multiple places where you need to check for error, then you need to duplicate the code you'd place in your `if` block. Typically a single-entry, single-exit approach is simpler in C and allow consolidating cleanup code. – jamesdlin Sep 19 '16 at 12:11
  • I had the impression that `goto cleanup` was more widespread then `do while(0)` in the linux kernel. Things could have changed since I looked at some linux kernel code or it may depend on experiences... – stefaanv Sep 19 '16 at 12:14
  • @Bathsheba @jamesdlin I was talking about using nested `if` statements checking for `!error_n` without loop instead of creating a one iteration loop with `if` checking for `error_n` to break the loop. – Thomas W. Sep 19 '16 at 12:23
  • 3
    @ThomasWilmotte When you have to do a lot of such checks, then all of the nested levels of indentation are cumbersome and harm readability. You either have to scroll horizontally (yuck) or wrap lines earlier than you otherwise would. (Also see http://stackoverflow.com/a/18507973/179715 ) – jamesdlin Sep 19 '16 at 12:27
3

Yes it's a common technique to avoid deep nesting, and actually preferable to goto;.

From point of readability its way better than goto statements. The scope and code flow of the loop is well defined, and you don't need to lookup the corresponding labels of the goto statements, which not necessarily appear below.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • 1
    why preferable to goto? Doesn't it have exactly the same effect? – 463035818_is_not_an_ai Sep 19 '16 at 11:54
  • 2
    @tobi303 It guarantees scope, and is better readable. With a `goto` statement you have to lookup the corresponding label (wich doesn't necessarily appear below the statement). – πάντα ῥεῖ Sep 19 '16 at 11:56
  • 2
    @tobi303 mentioning the (perfectly legal) keyword `goto` always risks starting a religious war. It's just one of those infectious dogmas that make their way into the human mind. – Richard Hodges Sep 19 '16 at 11:57
  • 4
    _"The scope and code flow of the loop is well defined"_ Just as it is with `goto`, at least in C++; [to believe otherwise is to buy into a common misconception](http://stackoverflow.com/a/7334968/560648). – Lightness Races in Orbit Sep 19 '16 at 12:02
  • @LightnessRacesinOrbit: nice plug for your excellent answer ;-) – Bathsheba Sep 19 '16 at 12:06
  • @Bathsheba: Shame I can't take it to the bank ^_^ – Lightness Races in Orbit Sep 19 '16 at 12:07
  • 1
    I disagree about preferability. `goto error`/`goto failure`/`goto cleanup` clearly documents the intent better than a bare `break` statement. IMO excessive indentation (which would happen due to the gratuitous `do`-`while` block) also harms readability. As for having to look for the `goto` labels, that's an apples to oranges comparison. The context of the question is about cases where a `goto` is interchangeable with breaking out of a loop. Finally, you can't directly use the `break` method if you're already within a loop or `switch` statement. – jamesdlin Sep 19 '16 at 12:18