Why use do { } while (0) in macro definition?
Solution 1
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)
Solution 2
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)
.
Solution 3
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)
.
Comments
-
ciphor about 2 years
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
-
moonshadow over 12 years...it does, but please don't...
-
Simon over 12 yearsof course, if you use naked if lines like that, you deserve for your code to break...
-
CoderSpinoza over 8 years@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
-
Simon over 8 years@CoderSpinoza apparently so, and if I were to work on the linux kernel then I would follow that style. Elsewhere, I'd avoid it.
-
Elvis Teixeira over 6 yearsA lot of C code repos use one line ifs without braces, and it is totally fine.
-
KRoy over 6 yearsIt reduces the number of if-else nesting.