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:
This expands to:
Which is, if sanely formatted:
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):
at using the macro. Again:
Which now becomes:
Which is the same as:
You might rejoin, why not just wrap the macro in curly-brackets? Why also have thedo/while(0) logic?This is why. Consider:
This becomes:
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.
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); |
if (!feral) bar(wolf); baz(wolf); |
if (!feral) bar(wolf); baz(wolf); |
#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); |
if (!feral) do { bar(wolf); baz(wolf); } while (0); |
if (!feral) { bar(wolf); baz(wolf); } |
#define foo(x) { bar(x); baz(x); }And:
if (!feral) foo(wolf); else bin(wolf); |
if (!feral) { bar(wolf); baz(wolf); }; else bin(wolf); |
相关文章推荐
- what is the purpose of using translatable in Android strings?
- [转] What is the point of redux when using react?
- What is the purpose of @SmallTest, @MediumTest, and @LargeTest annotations in Android?
- what is the purpose of __ASSEMBLY__?
- What do you think is the role of parents in preventing crime amongst young people?
- what is the purpose of channel coding?(信道编码的作用?)
- What is the purpose of the USB?
- What is the purpose of /etc/default?
- what is the purpose of the rptproj.user file
- ccah-500 第47题 What is the purpose of ZooKeeper in such a configuration
- What is the purpose of mock objects?
- What's the use of do while(0) when we define a macro?
- What Is the Purpose of This Book?
- what is the mean of "GPRINT Type" in cacti
- An incompatible version 1.1.1 of the Apache Tomcat Native library is installed, while Tomcat requires version 1.1.3
- what is the use of truncate command
- It is said that wars in the 21st century will be fought over water. Do you agree? What do you think can be done now to alleviate
- What is the maximum length of a URL
- What is the difference of x=x+3 and x+=3?
- What are the best ways to determine what port an application is using?