您的位置:首页 > 其它

What is the purpose of using do {...} while (0) in macros?

2014-12-25 12:47 453 查看
Thedo/while(0) pattern seen in many if not most macros in the Linux kernel and elsewhere has a specific purpose: It
is the only construct in C that lets you define macros thatalways work the same way, so that a semicolon after your macro always has the same effect,regardless of how the macro is used (with particularly emphasis on the issue
of nesting the macro in an if without curly-brackets).Let's consider an example:
#define foo(x)  bar(x); baz(x)
Say you used it like this:
foo(wolf);
This expands to:
bar(wolf); baz(wolf);
So far, so good. That does what you intended. But let's consider usage like this:

if (!feral)
foo(wolf);
This expands to:
if (!feral)
bar(wolf); baz(wolf);
Which is, if sanely formatted:
if (!feral)
bar(wolf);
baz(wolf);
That likely isn't what you intended. As shown, it isn't possible to write multistatement macros that do the right thing in all situations. You can't make macros behave like functions—withoutdo/while(0).Let's revisit our original macro, wrapped in do/while(0):
#define foo(x)  do { bar(x); baz(x); } while (0)
Now, this statement is functionally equivalent to the former. The do ensures the logic inside the curly-brackets executes, thewhile(0) ensures that happens but once. Same as without the loop. So what's different? Let's look
at using the macro. Again:
if (!feral)
foo(wolf);
Which now becomes:
if (!feral)
do { bar(wolf); baz(wolf); } while (0);
Which is the same as:
if (!feral) {
bar(wolf);
    baz(wolf);
}
You might rejoin, why not just wrap the macro in curly-brackets? Why also have thedo/while(0) logic?This is why. Consider:
#define foo(x)  { bar(x); baz(x); }
And:
if (!feral)
foo(wolf);
else
bin(wolf);
This becomes:
if (!feral) {
bar(wolf);
    baz(wolf);
};
else
bin(wolf);
Note the stray semicolon, which makes the else a dangling else. If you want people to be able to use your macro like a function and put semicolons where they belong, then this doesn't work.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: