Why use do { } while (0) in macro definition? [dup

2019-03-09 08:25发布

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

3条回答
淡お忘
2楼-- · 2019-03-09 08:55

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).

查看更多
smile是对你的礼貌
3楼-- · 2019-03-09 08:58

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楼-- · 2019-03-09 09:07

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)

查看更多
登录 后发表回答