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字幕 流程(一) .本篇 ...
随机推荐
- char[]数组与char *指针的区别
char[]数组与char *指针的区别 问题描述 虽然很久之前有看过关于char指针和char数组的区别,但是当时没有系统的整理,到现在频繁遇到,在string,char[], char *中迷失了 ...
- 通过gdb跟踪Linux内核装载和启动可执行程序过程
作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的:通过对一个简单的可执 ...
- 线性方法用于Binary clssification
到现在,我们已经学过三种线性方法:linear classification.Linear Regression.logistic Regression.这三种方法的核心都是,不同点在于:最小化的er ...
- BITED数学建模七日谈之二:怎样阅读数学模型教材
今天进入我们数学建模七日谈的第二天:怎样阅读数学建模教材? 大家再学习数学建模这门课程或准备比赛的时候,往往都是从教材开始的,教材的系统性让我们能够很快,很深入地了解前人在数学模型方面已有的研究成果, ...
- [算法] 冒泡排序 Bubble Sort
冒泡排序(Bubble Sort,台湾另外一种译名为:泡沫排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没 ...
- 30 分钟 Java Lambda 入门教程
Lambda简介 Lambda作为函数式编程中的基础部分,在其他编程语言(例如:Scala)中早就广为使用,但在Java领域中发展较慢,直到java8,才开始支持Lambda. 抛开数学定义不看,直接 ...
- homework-10
不多不说这是一次神奇的作业,作业一拖再拖,到最后发现.... 首先,在一开始的最大字数和问题实现图形界面主要是由我的小伙伴邹同学完成的,所以当我第一次看到说要显示详细运行过程的时候感到很迷茫. 第一感 ...
- CoffeeScript学习(1)——Quick Start
什么是CoffeeScript CoffeeScript 是一门编译到 JavaScript 的小巧语言. 在 Java 般笨拙的外表下, JavaScript 其实有着一颗华丽的心脏. Coffee ...
- 最长回文子串(Longest Palindromic Substring)-DP问题
问题描述: 给定一个字符串S,找出它的最大的回文子串,你可以假设字符串的最大长度是1000,而且存在唯一的最长回文子串 . 思路分析: 动态规划的思路:dp[i][j] 表示的是 从i 到 j 的字串 ...
- [iOS微博项目 - 1.3] - 内容对齐 TextAlignment & VerticalAlignment & HorizontalAlignment & contentMode
四个容易混淆的属性:1. textAligment : 文字的水平方向的对齐方式1> 取值NSTextAlignmentLeft = 0, // 左对齐NSTextAlignme ...