do{}while(0)

  在linux中,经常会看到do{}while(0)这样的语句,许多人开始都会疑惑,认为do{}while(0)毫无意义,因为它只会执行一次,加不加do{}while(0)效果是一样的,其实do{}while(0)

的用法主要在于宏定义中。

  这里用一个简单的宏来演示:

  #define SAFE_FREE(p) do{ free(p); p = NULL; } while(0)

  假设这里去掉do{...}while(0),即定义SAFE_FREE  为:

  #define SAFE_FREE(p) free(p); p = NULL;

  那么以下代码

  if(NULL != p)

    SAFE_FREE(p)

  else

    .../*do something*/

   会被展开为:

  if(NULL != p)

    free(p); p = NULL;

  else

    .../*do something*/

  展开的代码中存在两个问题

  1、因为if分支后有两个语句。导致else分支没有对应的if,编译失败

  2、假设没有else分支,则SAFE_FREE中的第二个语句无论if测试是否通过,都会执行。

  的确,将SAFE_FREE的定义加上{}就可以解决上述问题,即:

  #define SAFE_FREE(p) {free(p); p = NULL;}

  这样代码:

  if(NULL != p)

    SAFE_FREE(p)

  else

    .../*do something*/

  会被展开为:

  if(NULL != p)

    {free(p); p = NULL;}

  else

    .../*do something*/

   但是,在 c程序中,每个语句后加分号是一种约定俗成的习惯,那么,如下代码:

  if(NULL != p)

    SAFE_FREE(p);

  else

    .../*do something*/

  将被扩展为:

  if(NULL != p)

    {free(p); p = NULL;};

  else

    .../*do something*/

  这样,else分支就又没有对应的if了,编译将无法通过,假设用了do{} while(0),情况就不一样了,同样的代码会被展开为:

  if(NULL != p)

     do{ free(p); p = NULL; } while(0);

  else

    .../*do something*/

  不会再出现编译问题。 do{ } while(0)的使用完全是为了保证宏定义的使用者能无编译错误的使用宏,不对使用者做任何假设

linux do{} while(0)的更多相关文章

  1. Linux(RHEL7.0)下安装nginx-1.10.2

    查看当前系统版本是否支持 当前,nginx发布包支持以下Linux操作系统版本: RHEL/CentOS: Version Supported Platforms 5.x x86_64, i386 6 ...

  2. UEFI安装Kali Linux 1.1.0记录

    现在使用Kali Linux 1.1.0, UEFI启动,使用Fcitx的拼音输入法,词库实在不爽,将就写一写. 本文地址: http://www.cnblogs.com/go2bed/p/42954 ...

  3. debian7 请把标有“Debian GNU/Linux 7.1.0 _Wheezy_ - Official amd64 DVD Binary-1 20130615-23:06”的盘片插入驱动器“/media/cdrom/”再按回车键

    有时候,在通过apt-get install 安装软件的时候,会出现: 更换介质:请把标有“Debian GNU/Linux 7.1.0 _Wheezy_ - Official amd64 DVD B ...

  4. 如何在Ubuntu/CentOS上安装Linux内核4.0

    大家好,今天我们学习一下如何从Elrepo或者源代码来安装最新的Linux内核4.0.代号为‘Hurr durr I'm a sheep’的Linux内核4.0是目前为止最新的主干内核.它是稳定版3. ...

  5. window 远程在Linux(centOS7.0)上安装JDK以及配置环境变量

    本人是在windows 7 上安装了虚拟机,虚拟机安装的是linux(centOS7.0)系统现在在Windows 上安装SecureCRT 远程虚拟机的linux系统,安装JDK以及配置环境变量. ...

  6. Linux 进入 5.0 时代!

    Linux 进入 5.0 时代! 为什么 Linux 4.2 之后的版本不再是 4.21 而是 5.0? 如果你非要一个理由,那就是因为 Linux 4.x 的版本如今用手指与脚趾加在一起都要数不过来 ...

  7. 安装 Linux 内核 4.0

    大家好,今天我们学习一下如何从Elrepo或者源代码来安装最新的Linux内核4.0.代号为‘Hurr durr I'm a sheep’的Linux内核4.0是目前为止最新的主干内核.它是稳定版3. ...

  8. Linux下tomcat6.0与jdk安装

    Linux下tomcat6.0与jdk安装 步骤如下: 1. 上传apache-tomcat-6.0.37.tar.gz和jdk-6u13-linux-i586.bin至/usr/local 给这两个 ...

  9. Deepin15.8系统下安装QorIQ Linux SDK v2.0 yocto成功完美运行的随笔

    2019.2.17日:最终安装成功,完美解决! 2019.2.16日:最终安装未成功,但是过程中排除 了几个bug,前进了几步,仅供参考. 写在最前面,yocto安装是有系统要求的,Deepin 15 ...

  10. Linux安装php-7.0.16,完成php和apache的配置

    Linux安装php-7.0.16,完成php和apache的配置     版本:php-7.0.16.tar.gz,libxml2-2.9.2.tar.gz(php需要它的支持,首先安装它) 说明 ...

随机推荐

  1. java329 继承、类的高级概念

  2. nginx-编译安装 第一章

    nginx 第一章:编译安装 nginx 官网网站:http://nginx.org/en/ 1.基础说明 基本HTTP服务器功能其他HTTP服务器功能邮件代理服务器功能TCP/UDP代理服务器功能体 ...

  3. 从路由器镜像中提取uImage头信息

    uImage header为64字节,文件头为27 05 19 56 hexdump -C a.bin | grep "27 05 19 56" 或者 hd aa.bin | gr ...

  4. this指向问题,只提供案例,不做任何分析

    希望大家在测试的道路上找到答案,阔步前行 <script type="text/javascript"> /*this指向 console.log(this); fun ...

  5. Go 使用 JSON

    Encode 将一个对象编码成 JSON 数据,接受一个 interface{} 对象,返回 []byte 和 err func Marshal(v interface{}) {[]byte,err} ...

  6. robot framework---时间控件取值

    项目中遇到日期控件定位不了,网上各种找,并没有适合我的,目前通过Javascript已解决了,再次做个记录,方便自己日后查找,如有同样问题的同学也可以有个参考! 先说明,不同的定位方式是看开发同学如何 ...

  7. 基本设置_common_setting

    comment(备注) ID(请勿修改) Param(参数) 说明与格式 积分物品ID设置 1 60000 积分属性虚拟货币,存储在Auth库account表TokenAmount字段. 这里设置积分 ...

  8. 【Core】.NET Core 部署在Linux

    安装.NET  Core SDK 在CentOS上 1.右键打开命令行: 2.为了安装.NET,需要注册微软签名密钥和添加微软相关的支持.这个操作每台机器只能做一次. Add the dotnet p ...

  9. vue 2.0 使用replace时要点击路由多次才能返回

    项目中有一个选择机场的需求,从表单页面--->机场页面(选择出发机场)-->表单页面-->机场页面(选择到达机场); 如果只用push跳转的话,页面返回必然会返回机场选择页面. 所以 ...

  10. ubantu下git的连接和使用

    目录 操作命令 创建仓库,并提交一个readme文件. 文件改动怎么办 版本回退 版本库(Repository) 撤销修改 删除文件 远程仓库 添加远程库 本地有一个仓库,想要在GitHub上同步这个 ...