在开源软件里面经常可以看到这样的写法。

#define X(a) do { f1(a); f2(a); } while(0)

1. 主要作用是放在宏定义里面,避免宏带来的语法问题。

比如

#define DOSOMETHING()\
cmd1;\
cmd2; 而调用的时候
if(a>0)
DOSOMETHING(); 会有问题,需要用到上面提到的 而这时候,为什么不用 if (1) { ... } 呢? 有两方面原因:
首先,会多出不必要的分号,比如:
if (1)
my_code; 另外更重要的是,有if-else的问题:
if (1)
my_code;
else { ... }
当然了,如果定义成
#define X(a) if(1) { f1(a); f2(a); } else{}

就和下面的 do...while(0)一样安全了。但是上面的if-else写法不需要写分号;,有利有弊。
#define X(a) do { f1(a); f2(a); } while(0)

2. 还有一个重要原因是,可以用来取代goto跳转。

比如下面带goto的代码:

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

可以利用do...while(0)和break的配合,写成:

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

goto转换为do...while+break,在程序结构上、编译优化上,都有很多好处。我觉得。

3、避免空宏引起的warning

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

#define EMPTYMICRO do{}while(0)

我觉得,这个也可以用if-else来代替。

4、定义一个单独的函数块来实现复杂的操作,避免作用域或者命名空间冲突

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

(完)

C++ do{...}while(0)的好处的更多相关文章

  1. 宏定义中使用do{}while(0)的好处 (转载)

    宏定义中使用do{}while(0)的好处   #define MACRO_NAME(para) do{macro content}while(0)   的格式,总结了以下几个原因:   1,空的宏定 ...

  2. 使用do{ } while(0)的好处

    经常看到好多程序,尤其是linux相关的,使用do{}while(0)的写法,很明显内部程序最多只能执行一次,这样写的原因是什么呢?个人认为主要的原因是,如果不使用do{}while(0),那么当一个 ...

  3. 函数式宏定义用do...while(0)的好处

    函数式宏定义经常写成这样:<pre lang="c" escaped="true">#define device_init_wakeup(dev, ...

  4. HTTP 2.0的那些事

    转自:http://www.admin10000.com/document/9310.html 在我们所处的互联网世界中,HTTP协议算得上是使用最广泛的网络协议.最近http2.0的诞生使得它再次互 ...

  5. HTTP2.0那些事

    1. HTTP2.0的前世 http2.0的前世是http1.0和http1.1这两兄弟.虽然之前仅仅只有两个版本,但这两个版本所包含的协议规范之庞大,足以让任何一个有经验的工程师为之头疼.http1 ...

  6. http2.0与http1.X的区别

    此文只是方便重看,原文在:http://www.mamicode.com/info-detail-1199706.html 1.1 HTTP应用场景 http诞生之初主要是应用于web端内容获取,那时 ...

  7. http/2.0时代已经来临了!

    知识分享  文章转自:https://blog.csdn.net/g6U8W7p06dCO99fQ3/article/details/78906348 现在是资源共享的时代,同样也是知识分享的时代,如 ...

  8. Http 1.x弊端与Http 2.0比较

    HTTP2.0作为新版协议,改动细节必然很多,不过对应用开发者和服务提供商来说,影响较大的就几点. 新的二进制格式(Binary Format) http1.x诞生的时候是明文协议,其格式由三部分组成 ...

  9. nginx安装http2.0协议

    1.HTTP2协议 HTTP 2.0 的主要目标是改进传输性能,实现低延迟和高吞吐量.从另一方面看,HTTP 的高层协议语义并不会因为这次版本升级而受影响.所有HTTP 首部.值,以及它们的使用场景都 ...

随机推荐

  1. asp.net页面间传值方式

    使用asp.net开发项目,必然会在页面间进行传值,本文介绍几种常见的页面传值方式,仅作笔记,以便后续查找使用. 前提:新建两个页面:ValuePage.aspx,ObtainValue.aspx,本 ...

  2. Windows平台配置免安装的MySQL

    1.下载 官网下载免安装文件(本文使用的是mysql-5.6.33-win32.zip)解压到E:\MySQL\mysql-5.6.33打开E:\MySQL\mysql-5.6.33\my-defau ...

  3. Asp.Net alert 方法

    public static void ExcuteAlert(Page page, string strAlerts)        {            ClientScriptManager  ...

  4. csuoj 1507: 超大型LED显示屏

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1507 1507: 超大型LED显示屏 时间限制: 1 Sec  内存限制: 128 MB 提交:  ...

  5. 借助Glances Monitor,密切关注你的系统

    两种方法安装 glances 通常可以有两种方法安装 glances.第一种是通过编译源代码的方式,这种方法比较复杂另外可能会遇到软件包依赖性问题.还有一种是使用特定的软件包管理工具来安装 glanc ...

  6. 修改yv12像素值

    YV12内存布局 1 unsigned char *pY = (unsigned char *)pBuf; unsigned char *pV = pY + nWidth * nHeight; uns ...

  7. Java运行环境的配置

    Make sure you do not use the trailing semicolon: This will not work: set JAVA_HOME=C:\Program Files ...

  8. iOS性能优化:Instruments

    检测内存泄露:Instruments中的Leaks 前言 如果要检测内存泄露,我们会使用Xcode7自带的Instruments中的Leaks工具来检测. 现在的开发环境是ARC,所以很少会出现内存泄 ...

  9. LeetCode----66. Plus One(Java)

    package plusOne66; /* Given a non-negative number represented as an array of digits, plus one to the ...

  10. JSON下

    JSON下:目录一:把 JSON 文本转换为 JavaScript 对象二:JSON 实例 - 来自字符串的对象 一.把 JSON 文本转换为 JavaScript 对象JSON 最常见的用法之一,是 ...