tags:

views:

4766

answers:

6

Hey!

I've been seeing that expression for over 10 years now. I've been trying to think what it's good for. Since I see it mostly in #defines, I assume it's good for inner scope variable declaration and for using breaks (instead of gotos.)

Is it good for anything else? Do you use it?

+1  A: 

Have a look at this question.

Federico Ramponi
+7  A: 

It is a way to simplify error checking and avoid deep nested if's. For example:

do {
  // do something
  if (error) {
    break;
  }
  // do something else
  if (error) {
    break;
  }
  // etc..
} while (0);
Jere.Jones
er, factor it into a method, and use early return.
Dustin Getz
or... just use do { } while(0).
nickf
A: 

Generically, do/while is good for any sort of loop construct where one must execute the loop at least once. It is possible to emulate this sort of looping through either a straight while or even a for loop, but often the result is a little less elegant. I'll admit that specific applications of this pattern are fairly rare, but they do exist. One which springs to mind is a menu-based console application:

do {
    char c = read_input();

    process_input(c);
} while (c != 'Q');
Daniel Spiewak
It's available in C#, too, which doesn't have macros. I'm not sure why someone down-voted this reply but I see it as the almost-right answer, except it overlooked the explicit "0" in the while condition. Please, people, if you down-vote someone's reply please comment.
stimpy77
I wasn't the one to downvote; however, the question is very specific, and the answer is true in general but out of context.
ΤΖΩΤΖΙΟΥ
+8  A: 

It helps grouping multiple statements into a single one, so that a function-like macro can actually be used as a function. Suppose you have

#define FOO(n)   foo(n);bar(n)

and you do

void foobar(int n){
  if (n)
     FOO(n);
}

then this expands to

void foobar(int n){
  if (n)
     foo(n);bar(n);
}

Notice that the second call (bar(n)) is not part of the if statement anymore.

Wrap both into do{}while(0), and you can also use the macro in an if statement.

Martin v. Löwis
+31  A: 

It's the only construct in C that you can use to #define a multistatement operation, put a semicolon after, and still use within an if statement. An example might help:

#define FOO(x) foo(x); bar(x)

if (condition)
    FOO(x);
else // syntax error here
    ...;

Even using braces doesn't help:

#define FOO(x) { foo(x); bar(x); }

Using this in an if statement would require that you omit the semicolon, which is counterintuitive:

if (condition)
    FOO(x)
else
    ...

If you define FOO like this:

#define FOO(x) do { foo(x); bar(x); } while (0)

then the following is syntactically correct:

if (condition)
    FOO(x);
else
    ....
Greg Hewgill
Great answer but it would be even better with an example of using the do {} while(0); construct.
Jeff Yates
Sneaky! (padding for 10 character min comment)
Blank Xavier
+4  A: 

Good answer for this question is on this other stackoverflow question:

Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?

Michael Burr