do {...} while (0) in macros
If 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:
1
2
#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 Lovefrom 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:
1
#define foo(x) bar(x); baz(x)
Later you may call:
1
foo(wolf);
This will be expanded to:
1
bar(wolf); baz(wolf);
This is the expected output. Next let's see if we have:
1
2
if(!feral)
foo(wolf);
The expansion may not be what you expect. The expansion may be:
1
2
3
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:
1
#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 :
1
2
if(!feral)
do{ bar(wolf); baz(wolf); } while(0);
Semantically, it's the same as:
1
2
3
4
if(!feral) {
bar(wolf);
baz(wolf);
}
You might rejoin, why not justwrap the macro in curly-brackets? Why also have the do/while(0)logic? For example, we define the macro with curly bracket:
1
#define foo(x) { bar(x); baz(x); }
This is fine for the above if statement, but if we have below statement:
1
2
3
4
if(!feral)
foo(wolf);
else
bin(wolf);
The expanded code will be :
1
2
3
4
5
6
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.
do {...} while (0) in macros的更多相关文章
- 用m4 macros创建文本文件
用m4 macros创建文本文件 原文链接: http://ldp.linux.no/linuxfocus/ChineseGB/September1999/article111.html 补充阅读 ...
- ATL and MFC String Conversion Macros
ATL 7.0介绍了一些新的转换类和宏,为现有的宏提供了重要的改进.新的字符串转换类和名称宏的形式是:C 源类型 2[C] 目标类型[EX]其中:•源类型和目标类型描述如下表.• [C]是目标类型必须 ...
- 7、zabbix使用进阶(03)
节知识点: zabbix自动发现 web监控 zabbix自动发现 官网:https://www.zabbix.com/documentation/4.0/zh/manual/discovery/ ...
- Android Mokoid Open Source Project hacking
/***************************************************************************** * Android Mokoid Open ...
- CV_Assert
转:http://blog.csdn.net/ding977921830/article/details/46376847 Checks a condition at runtime and thro ...
- 基于Arduino的音乐动感节奏灯
1.音乐动感节奏灯是个什么东西? 前段时间听音乐觉得无聊,便想着音乐光听也没意思啊,能不能 “看见” 音乐呢?于是谷歌了一番,发现还真有人做了将音乐可视化的东西,那就是音乐节奏灯.说的简单点就是LED ...
- 恶意代码检测工具 -- Mathematics Malware Detected Tools
Mathematics Malware Detected Tools 重要:由于缺少测试数据,部分结论可能不正确.更多更准确的结论,还需要进行大量实验. 概述 mmdt(Mathematics Mal ...
- [Linux][C][gcc][tips] 在头文件中定义变量引发的讨论
概述 本人的原创文章,最先发表在github-Dramalife-note中.转载请注明出处. Define variable(s) in header file referenced by mult ...
- ZAM 3D 制作简单的3D字幕 流程(二)
原地址:http://www.cnblogs.com/yk250/p/5663907.html 文中表述仅为本人理解,若有偏差和错误请指正! 接着 ZAM 3D 制作简单的3D字幕 流程(一) .本篇 ...
随机推荐
- bzoj 3207 花神的嘲讽计划Ⅰ(哈希法+主席树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3207 [题意] 给定一个文本串,多次询问K长的模式串是否在文本[l,r]区间内出现. ...
- 配置Tomcat以指定的身份(非root)运行
本文依赖的环境: CentOS(大部分内容适用于其他Linux发行版) 已安装并配置好JVM环境 已安装并配置好gcc.make等编译工具 1. 下载Tomcat安装包并解压缩 cd /optwget ...
- 让sublime text 2更好地支持Python
SublimeCodeIntel: ~/.codeintel/config里加了python和pythonExtraPaths的路径(Mac): {"Python" : {&quo ...
- 【Hadoop学习】HDFS 短路本地读
Hadoop版本:2.6.0 本文系从官方文档翻译而来,转载请尊重译者的工作,注明以下链接: http://www.cnblogs.com/zhangningbo/p/4146296.html 背景 ...
- document.documentElement.clientHeight||document.documentElement.scrollHeight
在我看<JavaScript高级程序设计>(第三版)的时候,在clientHeight和scrollHeight那部分把我弄糊涂了. 原书是这样写的:( //宽度同理,就不仔细描述了.) ...
- Hibernate关联关系之——单向n-1
1 .单向 n-1 关联只需从n的一端可以访问1的一端 2.域模型: 从Order到Customer的多对一单向关联需要在Order类中定义一个Customer属性,而在Customer类中无需定义存 ...
- JSF 2 multiple select listbox example
In JSF, <h:selectManyListbox /> tag is used to render a multiple select listbox – HTML select ...
- zoj 1610 Count the Colors
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=610 Count the Colors Time Limit:2000MS ...
- hdu 5640 King's Cake(BestCoder Round #75)
King's Cake Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- JavaScript继承方式详解
原文链接 : http://segmentfault.com/a/1190000002440502 js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继 ...