Chinaunix首页 | 论坛 | 博客
  • 博客访问: 237009
  • 博文数量: 61
  • 博客积分: 125
  • 博客等级: 入伍新兵
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-23 23:28
文章分类

全部博文(61)

文章存档

2014年(37)

2013年(21)

2012年(3)

分类: C/C++

2014-08-09 10:47:16

在公司阅读项目代码时第一次遇到它们:#define 与 do()while(0) 的结合。

  1. #define libc_printf do{}while(0);

    当时看着有点懵,心想这样写有什么意义吗?do{}whiel(0)不就是一句废话么。但感觉不对劲,高手的世界怎会跟我这种菜鸟一样呢,肯定是没能读懂其中的奥妙。然后,不懂自然就问啦,度娘谷哥一番。发现#define 与 do()while(0) 是一种经典的用法。在linux内核代码中非常常见。而且不止我遇到的这一种用法,这就是孤陋寡闻的下场,学习的路还很长。下面就结合网上资料和自己的理解介绍下这两位”情侣“的故事。
    这两位情侣有如下几种结合(不要胡思乱想,我们是搞技术的,思想要单纯)

一、避免引用出错

这是此“情侣”结合最常见的用处。直接来代码,看看他们邂逅产生的火花。

    这些都是我们不想看到的悲剧,看样子问题还是得由猪脚来解决:

  1. #define MACROS()      do{  \
  2.                          code1(); \
  3.                          code2()\
  4.                          }while(0)

    来吧,随便你怎么用,我们都不会出差错!(秀恩爱是最无耻的),网上看到还有更有创意的写法:

  1. //不过只支持GCC 编译器
  2. #define MACROS()  ({ \
  3.                      code1();\
  4.                      code2();\
  5.                    })


二、
避免空宏引起的warning

    我遇到的就属于这种情况,如果定义空宏,编译器可能 warning ,为了避免它,就可以用do()while(0)来定义空宏。

  1. #define libc_printf      //空宏定义, 编译器可能会 warning
  2. #define libc_printf  do{}while(0);


三、
替代goto 语句

这里可能比较少见,用do(...)while(0) + break 可以替换goto ,避免goto的使用。(goto语句一般不提倡使用)

点击(此处)折叠或打开

  1. int fun()   // 此代码来源网络
  2. {
  3.  
  4.     somestruct* ptr = malloc(...);
  5.  
  6.     do{
  7.         dosomething...;
  8.         if(error)
  9.         {
  10.             break;
  11.         }
  12.  
  13.         dosomething...;
  14.         if(error)
  15.         {
  16.             break;
  17.         }
  18.         dosomething...;
  19.     }while(0);
  20.  
  21.     free(ptr);
  22.     return 0;
  23.  
  24. }
   C语言里肯定还有更多像他们这样美妙的组合,这些经典、创意的组合造就了C 语言之美。所以学习的路还很长,期待发现更多美好的事物!


阅读(1333) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~