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

#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. Eclemma各种安装方式以及安装失败解决

    在线安装方法一: 在eclipse的菜单栏点击 Help -> Install New Software -> add Name:eclemma (名称可以随便填) Location:ht ...

  2. angular 路由去除#号

    1.  路由启动          $locationProvider.html5Mode(true);  通过pushstatex修改url app.js define([ 'angular', & ...

  3. 《转》Spring4 Freemarker框架搭建学习

    这里原帖地址:http://www.cnblogs.com/porcoGT/p/4537064.html 完整配置springmvc4,最终视图选择的是html,非静态文件. 最近自己配置spring ...

  4. C语言 str2bin 和 bin2str 实现

    需求介绍 在编码或者调试过程中经常需要进行 字节码转换为 十六进制的字符串, 或者将 十六进制字符串 转换为 字节码的需求. 即:  字节码 (内存中存储的 01 串):    11111111 &l ...

  5. php日期,时间相关知识整理

    unix 时间戳:从1970年1月1日0点开始到当前时间所经过的秒数. 1.将日期转换为UNIX时间戳 mktime():可以自动校正越界的输入 原型 : mktime(hour,minute,sec ...

  6. ligerui_ligerTree_007_ligerTree动态加载节点

    ligerui:ligerTree:动态加载节点: 源码地址:http://download.csdn.net/detail/poiuy1991719/8571255 效果图: 代码:json.txt ...

  7. jQuery的deferred对象详解(转载)

    本文转载自: jQuery的deferred对象详解(转载)

  8. hibernate中load和get方法的区别

    1.读取时机不同(当lazy=true的时候)    load是采用延迟机制(load语句不读库,等使用非主键时才去读库),而get不采用延  迟机制(get语句时马上读库): 2.搜索不到数据时的情 ...

  9. RCNN--对象检测的又一伟大跨越 2(包括SPPnet、Fast RCNN)(持续更新)

    继续上次的学习笔记,在RCNN之后是Fast RCNN,但是在Fast RCNN之前,我们先来看一个叫做SPP-net的网络架构. 一,SPP(空间金字塔池化,Spatial Pyramid Pool ...

  10. C# property简介

    property专属的关键字就只有value.其他的性质实现都是用其他的方法的组合.property通过对一系列方法的灵活组合应用,能够间接地对私有的成员变量进行赋值操作和得到值.因为是间接地,私有变 ...