views:

285

answers:

6

I have compared gcc assembler output of

do{ 

//some code 

}while(0);

with

do{

//some code

 break; 
}while(1);

The output is equal, with or without optimization but..

It's always that way?

No experiment can prove theories, they can only show they are wrong

And because (I hope) programming is not an experimental science, and results can be predicted (at least simple things) I want to be sure next time I reeplace a break;}while(1); for the clearer (and less risky) while(0);

Thank you for reading

+3  A: 

The do while clauses are logically equivalent. If they are translated to the same byte code depends on the compiler at hand. I guess that most modern compilers will treat them equally.

kgiannakakis
+4  A: 

Edit: Upon reading various comments on the matter, I will admit that this answer is wrong. Sorry.

Instead of:

do{ 

//some code 

}while(0);

or:

do{

//some code

 break; 
}while(1);

I would just use:

//some code

I'm not 100% sure if you can do this in c++, but if you want to limit the scope of variables, and that is why you are doing this, just use curly braces by themselves:

{

 // Some Code

}
jjnguy
What if you want to break or continue?
jmucchiello
No, I don't want to limit the scope, it's for using break inside the block and reach the end
Hernán Eche
@jmucchiello: Use a `goto`. No seriously. Using a fake loop so that you can disguise a `goto` as some other word is more evil than using `goto` in the first place. (IMHO)
Charles Bailey
@jmucchiello I suppose I didn't consider that case. It seems to me that using other flow of control statements (if, then, else) would be more logical. But, then again, I don't think like a c programmer.
jjnguy
@Hernan If that is the case, then I think you should be using if/else blocks to achieve this. Or, even better, put the code into a method and use return to break out of the code early. Using a loop to do the job of if/else blocks seems broken to me.
jjnguy
@jjnguy: Why do you think this answer is wrong? It looks like a perfectly sensible answer to me.
Charles Bailey
@Charles, The loop construct is being used for different reasons that what I thought when I first answered. It now makes perfect sense why someone would want to do this. (But, i still don't think it's a good idea)
jjnguy
@jinguy: The main use I've seen for `do { ... } while 0` is in macros, since it allows you to write a single statement that contains multiples. A block is not quite equivalent to a single statement, since `{ ... };` is two statements while `do { ... } while 0;` is one (and that can matter: consider `if (foo) bar(); else baz;`). This is mostly applicable in C, because C++ has better ways to write function-type macros.
David Thornley
@David Thornley: I fully agree that it's a "good" C macro solution (if you have to be writing function-style macros, but I don't think that that's the situation in the question. @jjnguy: I still think you are correct to suggest not using an actual loop where a loop isn't the logical construct required.
Charles Bailey
My coworker uses this `do { } while(0)` with `breaks` all the time, it drives me nuts, never seen something so retarded. As Charles Bailey said, it's to hide `goto` or early `return` in a function. He uses it on code that is several hundert lines of code full of loops and `switch` when there are `break` statement I always have to search for the destination, is it in a switch, in another loop, in that big do nothing thing. A beautiful `goto` with a nice label is so much more clear. `goto finally` or `goto cleanup` or `goto handle_error` is a bit more clear than `break`, isn't it?
tristopia
@tristopia I agree. Using loops to do this seems silly.
jjnguy
A: 

EDIT based on your comment that you're using a while with breaks in order to be able to break out of the 'loop' when certain conditions have been met.

If this is what you're trying to accomplish:

do
{ 
  // processing step 1
  if( some_condition )
    break;
  // processing step 2
  if( some_condition )
    break;
  // etcetera..
} while(0)

...then just break the code you have in your while loop out to a stand-alone function with multiple returns:

void processing()
{

  // processing step 1
  if( some_condition )
    return;
  // processing step 2
  if( some_condition )
    return;
  // etcetera..
}

int main()
{
  // ...
  processing();
  return 0;
}
John Dibling
-1: making assumptions. do whiles can be used to exit early from a chain of functions calls (setup for instance) without an if/else ladder.
gbrandt
@gbrandt: Look again. It was completely unclear what the OP wanted until the "assumptions" were pointed out to the OP.
John Dibling
removed -1 on rewording of answer.
gbrandt
+14  A: 

There is a slight difference:

do {
  // code
  if ( condition )
    continue;
  // code
  break;
} while(1);

Will restart the loop when condition is true, whereas in the } while(0); version, the continue will be equivalent to break.

If no continue is present, then they should produce exactly the same code.

Gianni
Maybe they won't produce the same code, but they should do about the same thing.
zneak
This answer is correct.
jjnguy
Yes this answer is correct
Hernán Eche
can be always changed into something like: `do { /*code*/ } while(condition); /*code*/` at least, that specific example
ShinTakezou
@ShinTakezou Yes; the only practical reason might to use multiple conditions, and/or interlaced breaks.
Gianni
+5  A: 

The forms are not equivalent. This is an infinite loop:

do {
    continue;
    break;
} while (1);

This isn't:

do {
    continue;
} while (0);
Sean
+5  A: 

Markus' comment pointed me to this answer: the difference is when using continue keyword.

In this case:

int _tmain(int argc, _TCHAR* argv[])
{
    int i = 0;
    do {
        ++i;
        _tprintf(_T("Iteration %d\n"), i);
        if (i < 30) continue;
    } while(0);

    return 0;
}

you get only one iteration, while in this case:

int _tmain(int argc, _TCHAR* argv[])
{
    int i = 0;
    do {
        ++i;
        _tprintf(_T("Iteration %d\n"), i);
        if (i < 30) continue;
        break;
    } while(1);

    return 0;
}

you get 30 iterations. Tested under VS2008.

AOI Karasu
@AOI Karasu: I had to read this http://stackoverflow.com/questions/895827/what-is-the-difference-between-tmain-and-main-in-c to understand your code =P, yes that's the difference
Hernán Eche
@Hernán Eche: Sorry for the inconvenience. I use Microsoft's VS2008 for all my work :)
AOI Karasu