10

Possible Duplicate:
Are do-while-false loops common?

Is there a reason to have code like:

do {
    // a lot of code that only needs to be run once
} while (FALSE);

when the code isn't defining a macro? I know it's a trick when it comes to macros, but is there a reason for it in normal code?

Community
  • 1
  • 1
Anon
  • 1,290
  • 2
  • 16
  • 24
  • While I don't actually know, it would at least allow you to `break;` out of the "single-iteration loop" should you need to. In theory this could reduce the use of large nested `if` statements. – icabod Jan 07 '11 at 14:25
  • @marcog - Main difference is that appears to be a question about C. In particular, using them to implement the functionality of C++'s exceptions. Since this is explicitly a C++ question (where none of that would apply), I think they are different questions. – T.E.D. Jan 07 '11 at 15:53

6 Answers6

9

Well, it does allow you to use the break; (or continue) keyword for early exit if you have a need for that for some reason. That would be kinda ugly though. I'd really rather see it moved into its own routine, with the early exit implemented via a return; statement.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • 1
    Hmm, that is ugly. To me, it indicates a poor job breaking things into subroutines (as you now mention). – Justin Ardini Jan 07 '11 at 14:25
  • I agree with you. I've never liked unlimited loops, they just seem slimy to me :). It would be better to put the evaluation that exits the loop in the while condition - that's what it's there for. Anything else is usually just lazy programming. I equate break/continues as a veiled goto for lazy programmers, but that's my soapbox. :) – SRM Jan 07 '11 at 14:28
  • Do you prefer early exits via return statements instead? In some of the code I'm looking at, the author could just replace the break statement with a return and remove the do - while. Is that better? – Anon Jan 07 '11 at 14:32
  • @Anon: Yes, it is better. At least it does not misuse the `do-while` construct. Some people will argue that early return is a bad thing, though, but this is probably more a question of taste. Personally, I always use RAII which avoids most common problems with early returns. – Roman L Jan 07 '11 at 14:34
  • @Anon - Agree with 7vies, yes it is better. When I see do-while, I'm thinking loop, not straightline code. – T.E.D. Jan 07 '11 at 15:41
  • @SRM - You can see one of the questions below for my opinion on the "veiled goto" comment. I don't use `continue` much for some reason, but `break` can be a great tool for simplifying the code in loops with multiple exit conditions (particularly searches). Do your maintanence programmers a favor and don't complicate your code over matters of dogma. – T.E.D. Jan 07 '11 at 15:45
  • @T.E.D. It's not a matter of dogma. Like you said, do your maintanence programmers a favor. If you spell out your exit conditions explicitly there are no "side effects". I agree with you, break is sometimes a useful construct but it's still over used today. Even setting a flag makes the code much more readable. If you try to make your code "clever" by making it terse then the only person who will ever be able to debug it is you. I'm paraphrasing a quote but that's pretty much a good concept to follow. – SRM Jan 07 '11 at 16:25
  • Wrong. Nothing to do with breaks. The reason is that you must never end a macro in "}". Because if that is used in a statement like "if (..) MYMACRO(); else..." then you will get an error due to ";" after the expanded "}". Or worse will change the if nesting structure in subtle ways. – Tuntable Sep 23 '20 at 23:50
  • @Tuntable - The question specifically ended with "...when the code isn't defining a macro?" – T.E.D. Sep 24 '20 at 12:12
3

Well one reason for it would be if you want to break out at some point.

i.e.

do
{
   //some code that should always execute...

   if ( condition )
   {
      //do some stuff
      break;
   }

   //some code that should execute if condition is not true

   if ( condition2 )
   {
       //do some more stuff
       break;
   }

   //further code that should not execute if condition or condition2 are true

}
while(false);

In certain situations the resulting code is a little bit more clear / easier to understand if written as above.

ds27680
  • 1,993
  • 10
  • 11
  • 6
    You know what's always clearer than this and doesn't introduce an unnecessary block? `goto`. – Steve M Jan 07 '11 at 15:33
  • @Steve M - Actually agree. However, there's plenty of code there IMHO to justify its own routine. If you do that, you can use `return` instead, which is a wee bit less uncontrolled than a `goto`, and doesn't draw such an atavistic response from dogmatic developers. – T.E.D. Jan 07 '11 at 15:59
2

Such a construct is used as a kind of goto to be able to jump after the end of the loop using a break statement inside.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
  • 5
    I'm not a fan of calling other control structures "a kind of goto". **Every** control structure is "a kind of goto". Its the differences that make them interesting, not the similarities. – T.E.D. Jan 07 '11 at 14:26
  • 1
    Of course every control structure is a goto at the machine level, but at the language level, a `goto` is a `goto` statement and not an `if` statement. – Blagovest Buyukliev Jan 07 '11 at 14:35
2

I would not do this but:

I looks slightly more logical than just braces

int main()
{
    {
        std::ifstream file("Data");
        // DO STUFF

    }  // Data now closed.

    // LOTS OF STUFF SO YOU CANT SEE file2 below.

    // We can re-use data here as it was closed.
    std::ofstream file2("Data");
    // DO STUFF
 }

An unobservant maintainer may see the braces and think.
What the heck and remove them

int main()
{
    std::ifstream file("Data");
    // DO STUFF

    // LOTS OF STUFF SO YOU CANT SEE file2 below.

    // FAIL. data is still open from before.
    std::ofstream file2("Data");
    // DO STUFF
}

I suppose using the while tick at least make syou think about it (though an unobservant maintainer may still remove it).

int main()
{
    do
    {
        std::ifstream file("Data");
        // DO STUFF

    } while (false);

    // LOTS OF STUFF SO YOU CANT SEE file2 below.

    // We can re-use data here as it was closed.
    std::ofstream file2("Data");
    // DO STUFF
 }
Martin York
  • 257,169
  • 86
  • 333
  • 562
1

There is no reason to ever write a loop that is known, at compile time, to execute exactly once.

Doing so, in order to pretend that goto is written as break, is abusive.

EDIT:

I've just realised that my assertion about compile-time knowledge is false: I suppose you might do something complicated with conditional #defines that might mean that, at compile time for one build configuration, it is known to execute once, but for a different build configuration, it is executed multiple times.

#ifdef SOMETHING
#define CONDITION (--x)
#else
#define CONDITION 0
#endif
...
int x = 5
do{
  ...
} while(CONDITION)

However, the spirit of my assertion still stands.

Paul Butcher
  • 6,902
  • 28
  • 39
  • +1. `do while(false)` is a horrible anti-idiom outside of macros that simulate inline functions (which are their own brand of horrible). Also, if I ever saw a `#define` like that in real code, I would flip out. – Steve M Jan 07 '11 at 15:37
  • Yeah, the `#define` is a rather crazy example, and I can't come up with a justification for using it IRL. I just didn't want some pedant giving me a lesson on the precompiler. – Paul Butcher Jan 07 '11 at 15:55
0

It can be used to implement a behavior similar to goto statement, or say jump behavior!

See this:

do
{       
   if (doSomething() != 0) break; //jump
   if (doSomethingElse() != 0) break; //jump
   ...
   if (doSomethingElseNew() != 0) break; //jump
 } while(false);

 //if any of the break encountered, execution can continue from here, just after the do-while block! 

 // statement1
 // statement2
 // statement3
 // so on

Taken from here: Are do-while-false loops common?

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851