29

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

I met code like below:

#define ev_io_init(ev,cb,fd,events) \ do { \ ev_init ((ev), (cb)); \ ev_io_set ((ev),(fd),(events)); \ } while (0) 

I want to know why the author use do { } while (0) here. Is there any difference with this?

#define ev_io_init(ev,cb,fd,events) { \ ev_init ((ev), (cb)); \ ev_io_set ((ev),(fd),(events)); \ } 

BTW: the code is from libev, ev_local.h

0

3 Answers 3

36

Consider if( something ) function1(); else function2();

If function1() is actually a macro, just using { } requires you to omit the semicolon at the point of use, but do { } while(0) lets you use exactly the same syntax as for a real function.

(Not using any kind of block construct at all would just generate completely broken code, natch)

Sign up to request clarification or add additional context in comments.

Comments

27

Enclosing code with a loop allows for a preprocessor directive to execute multiple statements without "breaking" if-else-constructs. Consider the following:

#define DO_SOMETHING() a();b();c(); void foo() { // This is ok... DO_SOMETHING(); } void bar() { // ...whereas this would trigger an error. if (condition) DO_SOMETHING(); else blah(); } 

The second example breaks the if-else-construct because three statements are followed by an else clause. To allow for it to correctly substitute, the instructions in DO_SOMETHING should be enclosed with a do { ... } while(0).

4 Comments

of course, if you use naked if lines like that, you deserve for your code to break...
@Simon But doesn't linux kernel coding style advice us to use naked if else lines for one line block? kernel.org/doc/Documentation/CodingStyle
@CoderSpinoza apparently so, and if I were to work on the linux kernel then I would follow that style. Elsewhere, I'd avoid it.
A lot of C code repos use one line ifs without braces, and it is totally fine.
16

A do{}while(0) allows you to break from the loop:

do{ expr1; foo(); if ( cond ) break; expr2; goo(); } while (0); 

It's the same as a simple block {...} except that you can break execution when you want with the break statement. You couldn't do that in a simple code block, unless you have multiple checks, which can get cumbersome. It still gets executed once, because of the condition while(0).

2 Comments

...it does, but please don't...
It reduces the number of if-else nesting.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.