22

When looking through some code that was handled by another employee, I see a lot of code written in:

do{
    ...
}while(false);

What advantage (if any) does this provide?

Here is more of a skeleton that is happening in the code:

try{
    do{
        // Set some variables

        for(...) {
            if(...) break;
            // Do some more stuff
            if(...) break;
            // Do some more stuff
        }
    }while(false);
}catch(Exception e) { 
    // Exception handling 
}

Update:

C++ Version:
Are do-while-false loops common?

Community
  • 1
  • 1
Ascalonian
  • 14,409
  • 18
  • 71
  • 103

14 Answers14

27

Maybe it was done to be able to jump out of the "loop" at any time, e.g:

do
{
    ...
    if (somethingIsWrong) break;
    //more code
    ...
}
while(false);

But as others have said, I wouldn't do it like this.

M4N
  • 94,805
  • 45
  • 217
  • 260
  • 6
    Yeah, let's hack around the fact that our language doesn't have `goto`! – Michael Myers Sep 18 '09 at 14:55
  • I considered this, but given that a simple `if` statement (or horror, a `goto`) would do the job much more simply, I doubt it somewhat. – Noldorin Sep 18 '09 at 14:55
  • 4
    Wow - it's a Java-style goto! (but it's begging to be a function with a conditional return instead...) – moonshadow Sep 18 '09 at 14:56
  • 2
    @mmyers: it more or less the same as (ab-)using exceptions for flow control – M4N Sep 18 '09 at 14:56
  • Although you don't need it in Java as you can label the loop. – Tom Hawtin - tackline Sep 18 '09 at 14:59
  • 2
    I'm fairly sure that the only way to make this more convoluted is to use a try {} finally {} block somewhere in between. This code makes me sad. – Malaxeur Sep 18 '09 at 15:05
  • moonshadow: Why would abusing return be any better? You would be splitting the existing method at possibly a very awkward point. – Tom Hawtin - tackline Sep 18 '09 at 15:10
  • Noldorin: If there are multiple `if`-`breaks`, the equivalent `if` tree would be disappearing off the right hand side of the screen. – Tom Hawtin - tackline Sep 18 '09 at 15:11
  • 3
    @Tom, because you *know* in what method you are when you see that *return*. But if you see a "break", you usually think "oh, that's breaking out of the loop - wait, LOOP??", it is just confusing i think. – Johannes Schaub - litb Sep 18 '09 at 15:16
  • 1
    In the OPs question the break is breaking out of an inner for loop and not the do while loop. – pjp Sep 21 '09 at 08:10
  • @fortran: Yes, for values of "has" equaling "will recognize and give a compile error if you use". – Michael Myers Mar 05 '10 at 15:23
  • @mmeyers I see that this is the current behaviour, but I'd swear that long, long time ago, when I had my first programming classes at the university (circa 2000), a fellow student surprised the teachers using `goto` in a Java assignment xD... I have to research if early Java 1.1 really supported that or I am being tricked by my memory. – fortran Mar 05 '10 at 16:35
17

In Java, there is no reason to do this.

In C, this is a common idiom when defining macros:

Consider:

#define macro1 doStuff(); doOtherStuff()
#define macro2 do{ doStuff(); doOtherStuff(); } while( false )

if( something ) macro1; // only the first statement in macro1 is executed conditionally
if( something ) macro2; // does what it looks like it does

...but macros in C are evil and should be avoided if at all possible.

Does your coworker come from a C background?

moonshadow
  • 86,889
  • 7
  • 82
  • 122
14

No advantage. Don't do it.

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
7

It can be used to goto the end of a block which can be used to avoid a bunch nested if/then blocks.

do {
    if (done()) continue;
    // do a bunch of stuff
    if (done()) continue;
    // do a bunch more stuff
    if (done()) continue;
    // do even more stuff
} while (false);
cmac
  • 191
  • 2
  • 4
4

This is used in C to define block inside macro. See this for example.

Example, the following is invalid:

#define f(x) { g(x); h(x); }

if (x >= 0) f(x); else f(-x);

but with this definition, it will work:

#define f(x) do { g(x); h(x) } while(false)
alex
  • 74,215
  • 9
  • 49
  • 57
3

It is useless, but the coder could have used a multiple break commands to do some weird exception handling.

do{
if(<something>){...}else{break}
if(<something else>){...}else{break}
...
}while(false)

Granted its stupid, but I did find something like in a old c program once

Rodrigo
  • 163
  • 2
  • 9
  • Just ran into this today. Found this construct in the body of a C++ method and wondered, WTF? Google led me here and this seems the most likely answer. The original coder had multiple if (errorCond) { /* do something */ break; } statements within the do..while block. The only advantage I can see is that provides one point of return from the method (at the end of the method, as is the case in the code I'm staring at) rather than several. I wouldn't code it that way, but I can see why it was done. – Jon Oct 01 '12 at 20:03
2

Your intuition is right. That is a completely useless thing to do.

It is possible that whoever coded it originally had something other than false as the condition, and simply changed it to false rather than removing the entire block not to lose this "history" of the code. This is a just clutching at straws however. To be quite frank it's just a plain example of a tautology, which has no place in code.

Noldorin
  • 144,213
  • 56
  • 264
  • 302
  • Woah, what's with the sudden down-votes? It is courtesy to leave a comment when you down-vote, and the reason has not already been explained! – Noldorin Sep 18 '09 at 15:03
  • +1 to get your post upwards again. However, i can imagine some people are confused by your analogy with "logical tautology" and think that you talk about "false" being a tautology. Can you please elaborate on that analogy? – Johannes Schaub - litb Sep 18 '09 at 15:14
  • @litb: Cheers. And yeah, I used the wrong sort of tautology there perhaps. It is certainly a tautology in the common sense of the word: the fact that you write the code once, then add `do { ... } while (false)` again (unnecessarily) specifies that it should be added once. – Noldorin Sep 18 '09 at 15:18
1

In pretty much every language other than C/C++ this provides no tactical advantage.

In C/C++ there is a case with macros where do/while(false) makes it easier to expand a macro safely into multiple statements. This is advantageous when the macro otherwise looks like a normal function call.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
1

Have a look at this question

The OP asks about this exact construct and explains some reasons for using it. The consensus seems to be that it's a bad thing to do.

Community
  • 1
  • 1
Glen
  • 21,816
  • 3
  • 61
  • 76
1

As a placeholder for a future when some other condition is put in place of false.

mob
  • 117,087
  • 18
  • 149
  • 283
1

It could be used to skip execution of some code (like a goto or something) but when I look at it again, there seems to be a for loop (where the if(...) break; statements are) in the do-while. Otherwise, I would say that it would be a Java version of a goto...

1

I've used this convention for years! It's most useful when you have a "pipeline" of processing and/or conditional checks. It simply avoids multiple levels of nested if() statements and thus makes the code (much) easier to read. Yes there are alternatives like try/catch and I only use this style in certain thin/lower-level situations.

I start the "loop" (never actually loops) with a comment like...

// Error loop (never loops)

The error-loop is...

set errorCode = fail;
do {
  if (this)
    break;

  if (that)
    break;

  // Success
  set errorCode = ok;

  // Alternative Success
  errorCode = doWhatever();
} while (false);

Consider this style if you have a bunch of nested if() statements and your indents go more than 3 levels deep.

I've used this convention in Perl, C/C++, Java and Delphi/Pascal.

pds
  • 11
  • 1
0

I'm going to guess the author of that didn't trust his code so he used to run it a couple times to see if that made it work more and this is the archeological remains of that.

Ben S
  • 68,394
  • 30
  • 171
  • 212
0

The only reason I can think of is to create a block to make variables declared within the {...} more tightly scoped, but there are better ways of doing this (like creating functions, or just creating blocks - hat tip to Pete Kirkham).

Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212