linux内核和其他一些开源的代码中,经常会遇到这样的代码:

do{...
}while(0)

这样的代码一看就不是一个循环,do..while 表面上在这里一点意义都没有,那么为什么要这么用呢?

实际上,do{...}while(0) 的作用远大于美化你的代码。查了些资料,总结起来这样写主要有以下几点好处:

1、辅助定义复杂的宏,避免引用的时候出错

举例来说,假设你需要定义这样一个宏:

#define DOSOMETHING()\foo1();\foo2();

这个宏的本意是,当调用 DOSOMETHING() 时,函数 foo1() 和 foo2() 都会被调用。但是如果你在调用的时候这么写:

if(a>0)DOSOMETHING();

因为宏在预处理的时候会直接被展开,你实际上写的代码是这个样子的:

if(a>0)foo1();
foo2();

这就出现了问题。那么仅仅使用{}将foo1()和foo2()包起来行么?

我们在写代码的时候都习惯在语句右面加上分号,如果在宏中使用{},代码里就相当于这样写了:“{...};”,展开后就是这个样子:

if(a>0)
{foo1();foo2();
};

这样甚至不会编译通过。所以,很多人才采用了do{...}while(0);

#define DOSOMETHING() \do{ \foo1();\foo2();\}while(0)\...if(a>0)DOSOMETHING();...

这样,宏被展开后,才会保留初始的语义。

2、避免使用goto对程序流进行统一的控制

有些函数中,在函数 return 之前我们经常会进行一些收尾的工作,比如 free 掉一块函数开始 malloc 的内存,goto 一直都是一个比较简便的方法:

int foo()
{somestruct* ptr = malloc(...);dosomething...;if(error){goto END;}dosomething...;if(error){goto END;}dosomething...;
END:free(ptr);return 0;
}

由于 goto 不符合软件工程的结构化,而且有可能使得代码难懂,所以很多人都不倡导使用,那这个时候就可以用 do{}while(0) 来进行统一的管理:

int foo()
{somestruct* ptr = malloc(...);do{dosomething...;if(error){break;}dosomething...;if(error){break;}dosomething...;}while(0);free(ptr);return 0;
}

这里将函数主体使用 do()while(0) 包含起来,使用 break 来代替 goto,后续的处理工作在 while 之后,就能够达到同样的效果。

3、避免空宏引起的 warning

内核中由于不同架构的限制,很多时候会用到空宏,在编译的时候,空宏会给出 warning,为了避免这样的 warning,就可以使用 do{}while(0) 来定义空宏:

#define EMPTYMICRO do{}while(0)

4、定义一个单独的函数块来实现复杂的操作

当你的功能很复杂,变量很多你又不愿意增加一个函数的时候,使用do{}while(0);,将你的代码写在里面,里面可以定义变量而不用考虑变量名会同函数之前或者之后的重复。

转载于:http://www.spongeliu.com/415.html

(SAW:Game Over!)

do{...}while(0) 的意义和用法相关推荐

  1. 【转】do{...}while(0)的意义和用法

    转自:http://blogread.cn/it/article/5907 linux内核和其他一些开源的代码中,经常会遇到这样的代码: do{... }while(0) 这样的代码一看就不是一个循环 ...

  2. shell中$0,$?,$!等的特殊用法

    shell中$0,$?,$!等的特殊用法 (2011-03-01 17:38:00) 转载▼ 标签: it   变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行 ...

  3. duilib各种布局的作用,相对布局与绝对布局的的意义与用法

    duilib各种布局的作用,相对布局与绝对布局的的意义与用法 原文  http://blog.csdn.net/zhuhongshu/article/details/38531447 主题 Duili ...

  4. C语言中反斜杠“\“的意义和用法

    在阅读C语言代码经常可以看到代码中出现反斜杠"",不是很明白它的意思,遂对反斜杠""的意义和用法进行查询和总结记录: 转义字符 非常常用的一种用法,在反斜杠后面 ...

  5. python各种常用符号的意思_写一篇专门介绍python中各种符号的意义及用法

    挖槽,小米今天上市就破发了,好多认购的小伙伴有点慌了,其实对于小帅b来说这很正常,没必要慌,保持持有就好了,相信小米会越来越牛逼的.小米和可能会成为互联网新一代的霸主主一,到时候可能就不是BAT了,而 ...

  6. 【转】Hibernate的Generator属性有7种class,本文简略描述了这7种class的意义和用法。...

    转自:http://hi.baidu.com/zhang_zhu_1/item/5cfcf1a98b86e88a1410733b [转]Hibernate的Generator属性有7种class,本文 ...

  7. 1---结构体中最后一个成员为[0]长度数组的用法

     结构体中最后一个成员为[0]长度数组的用法 2012-04-27 16:03:58 分类: C/C++ 这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:  1.不需要初始 ...

  8. c语言static. volatile,嵌入式系统C语言重点语法const、volatile、static、堆栈等的意义及用法...

    原标题:嵌入式系统C语言重点语法const.volatile.static.堆栈等的意义及用法 在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场. 要点:堆, ...

  9. java this$0_java中this$0的含义及用法

    java中this$0的含义及用法 (2012-01-19 22:43:33) 标签: 杂谈 java中this$0的含义及用法,具体case是这样的: 通过测试工具去探测界面UI上的控件FlatBu ...

最新文章

  1. Android WebView使用与JavaScript使用
  2. Excel信息提取之二
  3. 【机器学习算法-python实现】svm支持向量机(2)—简化版SMO算法
  4. php打印预览jquery,php 实现打印预览的功能
  5. linux进程间命名管道,Linux进程间通信
  6. Html5 Canvas动画基础碰撞检测的实现
  7. Oracle 11g R2 RAC上配置TAF和Load balance
  8. pageoffice 选中部分文字 添加书签和空白处添加书签 删除空白以及内容书签
  9. android 4.4.2截屏方法,Android截屏截图的几种方法总结
  10. 凤凰x86 卡android,卡ANDROIDx86_64的解决办法
  11. 微信支付-超详细java开发-小程序对接
  12. 【快讯通知】江苏省2022年度社会保险有关基数通知
  13. 基于SSM的宠物医院信息系统设计与实现
  14. APS系统如何选型?(下)
  15. 【计算机视觉与深度学习】全连接神经网络(一)
  16. 专家谈房产两难:力图房价回归理性 担心地产崩溃
  17. 不同业务场景Cas客户端(Java业务系统)接入
  18. web前端-CSS Border(边框)-011
  19. bom翻译中文_BOM是什么意思中文翻译
  20. Photoshop 2021 Win10系统总安装失败,打不开,501错误等,如何解决安装教程!

热门文章

  1. html中name和id的区别 [ZT]
  2. mysql创建唯一索引_mysql创建唯一索引
  3. linux设置NO_PROXY绕过代理
  4. yumdownloader和 repotrack下载rpm包
  5. 使用Maven 实现打包生成一个可执行jar包:附详细配置解释说明
  6. linux ubuntu/deepin与Windows时间不同步解决办法(双系统)
  7. (提示)ubuntu16.04通过sealos安装k8s,需要重新部署apply一下calico组件
  8. Linux正则表达式判断是否是数字示例
  9. Scala集合数据结构特点
  10. scala reduceLeft和reduceRight执行分析