文档章节

do {...} while (0) in macros

robslove
 robslove
发布于 2015/06/14 14:58
字数 442
阅读 66
收藏 3

 you are a C programmer, you must be familiar with macros. They are powerful and can help you ease your work if used correctly. However, if you don't define macros carefully, they may bite you and drive you crazy. In many C programs, you may see a special macro definition which may seem not so straightforward. Here is one example:

#define __set_task_state(tsk, state_value)      \
    do { (tsk)->state = (state_value); } while (0)

There are many this kind of macros which uses do{...}while(0) in Linux kernels and other popular C libraries. What's the use of this macro? Robert Love from Google(previously worked on Linux kernel development) gives us the answer.

do{...}while(0) is the only construct in C that lets you define macros that always 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). 

For example:

#define foo(x)  bar(x); baz(x)

Later you may call:

foo(wolf);

This will be expanded to:

bar(wolf); baz(wolf);

This is the expected output. Next let's see if we have:

if (!feral)
    foo(wolf);

The expansion may not be what you expect. The expansion may be:

if (!feral)
    bar(wolf);
baz(wolf);

It isn't possible to write multistatement macros that do the right thing in all situations. You can't make macros behave like functions—without do/while(0).


If we redefine the macro with do{...}while(0), we will see:

#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, the while(0) ensures that happens but once. Same as without the loop.For the above if statement, it will be :

if (!feral)
    do { bar(wolf); baz(wolf); } while (0);

Semantically, it's the same as:

if (!feral) {
    bar(wolf);
    baz(wolf);
}

You might rejoin, why not just wrap the macro in curly-brackets? Why also have the do/while(0) logic? For example, we define the macro with curly bracket:

#define foo(x)  { bar(x); baz(x); }

This is fine for the above if statement, but if we have below statement:

if (!feral)
    foo(wolf);
else
    bin(wolf);

The expanded code will be :

if (!feral) {
    bar(wolf);
    baz(wolf);
};
else
    bin(wolf);

This is a syntax error.

In conclusion, macros in Linux and other codebases wrap their logic in do/while(0) because it ensures the macro always behaves the same, regardless of how semicolons and curly-brackets are used in the invoking code.


本文转载自:http://www.pixelstech.net/article/1390482950-do-%7B-%7D-while-%280%29-in-macros

共有 人打赏支持
上一篇: RTTI
下一篇: IOS屏幕旋转
robslove

robslove

粉丝 4
博文 181
码字总数 78228
作品 0
成都
程序员
私信 提问
zabbix使用过程中遇到的问题与解决方法(2)

一、旧版本中很多trigger不能用,比如下面的一个trigger expression是这样的::system.cpu.load[percpu,avg5].avg(5m)}>{$CPU_LOAD_NUM_W_GT_N},其中,CPU_LOAD_NUM_W_GT_N不是具体的数值 ...

yangjingangel
06/26
0
0
HPC Template Library, A Supplement to the STL

Download source Download HTLDocs052 Author: Anthony Daniels Introduction This package is intended to provide the user with threadsafe containers and classes for applications in ......

trident99
2017/12/15
0
0
安装util-macros,make 不成功,make: Nothing to be done for `all'

~/wayland/util-macros-1.19.0$ ./configure --prefix=$WLD checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking f......

Areas
2015/10/06
459
0
网络编程之IPv4和IPv6的互通性剩余小知识点(二)

1. IPv6 Address-Testing Macros The first seven macros test the basic type of IPv6 address. The final five macros test the scope of an IPv6 multicast address. 2. 总结 An IPv6 se......

lovestackover
03/22
0
0
__STDC_LIMIT_MACROS 和 __STDC_CONSTANT_MACROS

Question: I see this in the standard C++ libraries for my system, as well as some of the headers in a library I'm using. What are the semantics of these two definitions? Is ther......

长平狐
2013/03/04
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

AI赋能一键自动检测:页面异常、控件异常、文本异常

摘要: 1.前言 闲鱼质量团队一直致力于交付高质量的app给用户,当前随着AI技术不断发展,TensorFlow大热,也给测试手段带来了更多种可能,本文接下来给大家介绍AI在闲鱼测试的一点实践:如何...

阿里云官方博客
20分钟前
0
0
Microsoft Remote Desktop For Mac

地址:https://rink.hockeyapp.net/apps/5e0c144289a51fca2d3bfa39ce7f2b06/ 解决国内App store不能下载的问题。

Cheuker
31分钟前
1
0
原地打印刷新(倒计时)

原地打印刷新(倒计时) 代码如下 from time import sleepfor i in reversed(range(1, 11)): print("\r倒计时:{}秒".format(i), end="") sleep(1)...

_Change_
43分钟前
0
0
php,vue,vue-ssr 做出来的页面有什么区别?

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由shirishiyue发表于云+社区专栏 目前我这边的web页面,都是采用php+smarty模板生成的,是一种比较早期的开发模式。好处是没...

腾讯云加社区
49分钟前
2
0
安卓的切图规范

Android UI 切图命名规范、标注规范及单位描述 很多UI设计师做APP切图都会有两套,一套是Android的,一套是IOS的。IOS我这边暂不作讲解,因为我本人也不是开发IOS。这里整理一下我在Android...

mo311
54分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部