在公司阅读项目代码时第一次遇到它们:#define 与 do()while(0) 的结合。
- #define libc_printf do{}while(0);
当时看着有点懵,心想这样写有什么意义吗?do{}whiel(0)不就是一句废话么。但感觉不对劲,高手的世界怎会跟我这种菜鸟一样呢,肯定是没能读懂其中的奥妙。然后,不懂自然就问啦,度娘谷哥一番。发现#define 与 do()while(0) 是一种经典的用法。在linux内核代码中非常常见。而且不止我遇到的这一种用法,这就是孤陋寡闻的下场,学习的路还很长。下面就结合网上资料和自己的理解介绍下这两位”情侣“的故事。
这两位情侣有如下几种结合(不要胡思乱想,我们是搞技术的,思想要单纯):
一、避免引用出错
这是此“情侣”结合最常见的用处。直接来代码,看看他们邂逅产生的火花。
这些都是我们不想看到的悲剧,看样子问题还是得由猪脚来解决:
- #define MACROS() do{ \
- code1(); \
- code2(); \
- }while(0)
来吧,随便你怎么用,我们都不会出差错!(秀恩爱是最无耻的),网上看到还有更有创意的写法:
- //不过只支持GCC 编译器
- #define MACROS() ({ \
- code1();\
- code2();\
- })
二、避免空宏引起的warning
我遇到的就属于这种情况,如果定义空宏,编译器可能 warning ,为了避免它,就可以用do()while(0)来定义空宏。
- #define libc_printf //空宏定义, 编译器可能会 warning
- #define libc_printf do{}while(0);
三、替代goto 语句
这里可能比较少见,用do(...)while(0) + break 可以替换goto ,避免goto的使用。(goto语句一般不提倡使用)
点击(此处)折叠或打开
- int fun() // 此代码来源网络
- {
- somestruct* ptr = malloc(...);
- do{
- dosomething...;
- if(error)
- {
- break;
- }
- dosomething...;
- if(error)
- {
- break;
- }
- dosomething...;
- }while(0);
- free(ptr);
- return 0;
- }
C语言里肯定还有更多像他们这样美妙的组合,这些经典、创意的组合造就了C 语言之美。所以学习的路还很长,期待发现更多美好的事物!