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

本文解释了Linux内核和其他地方常见的do/while(0)宏模式,它允许定义始终一致行为的宏,确保在使用时能够正确处理嵌套情况,避免意外的语法错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值