#define XXX do{ XXX } while(0) 为什么使用

时常会遇到一个非常"奇怪的宏定义", rt.(欧西巴...思考不够深刻啊, 皮鞭, 啪啪啪)

近期又遇到这家伙了,Quora上面Love神回答了这个问题, 我也就顶礼膜拜

http://www.quora.com/What-is-the-purpose-of-using-do-while-0-in-macros

这是C语言里面宏定义的时候,不会造成歧义或副作用的一种经常使用技巧.

考虑一下情况

#define foo(x)  bar(x); baz(x)
foo(wolf);

常规的,扩展成例如以下代码:

bar(wolf); baz(wolf);

这都还好,没啥问题.可是假设遇到if推断语句了,看看以下的样例.

f (!feral)
foo(wolf);

这就扩展成了以下的形式,(⊙o⊙)看,是不是出现了你不想要粗线的情况捏?

这里if语句仅仅能作用于第一个bar()函数,无法作用于第二个baz().可是这样的方式非常可能不是程序猿的本意.

本意就是把foo单做一个总体嘛~

if (!feral)
bar(wolf); baz(wolf);

等价于例如以下形式

if (!feral)
bar(wolf);
baz(wolf);

离开了 do/while(0)你就别想把宏定义玩的跟函数一样一样的~



假设使用这样的技巧定义宏定义,

#define foo(x)  do { bar(x); baz(x); } while (0)

还是这个宏定义,这么用

f (!feral)
foo(wolf);

就变成了例如以下形式.

if (!feral)
do { bar(wolf); baz(wolf); } while (0);

等价于

if (!feral) {
bar(wolf);
baz(wolf);
}

你可能会想,用以下这样的方式,加个{}不就解决这个问题了么?干嘛害的要do{} while(0)?

考虑例如以下情况

#define foo(x)  { bar(x); baz(x); }

if (!feral)
foo(wolf);
else
bin(wolf);

这就变成了

if (!feral) {
bar(wolf);
baz(wolf);
};
else
bin(wolf);

注意!这里使得else变成了"臭名昭著的"dangling else.

版权声明:本文博主原创文章,博客,未经同意不得转载。

#define XXX do{ XXX } while(0) 为什么使用的更多相关文章

  1. Error Domain=ASIHTTPRequestErrorDomain Code=8 "Failed to move file from"xxx/xxx"to"xxx/xxx"

    今天真的好高兴呀 我解决了一个折磨了我一周的问题,真的是激动地要哭出来了,为了这个问题,我嘴也烂了,头发抓了一地啊.虽然解决方法,最后还是展现出了“百度”的伟大,但是我还是很开心,在这里我展示一下我的 ...

  2. C语言中宏定义(#define)时do{}while(0)的价值(转)

    C语言中宏定义(#define)时do{}while(0)的价值 最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总 ...

  3. Springboot 2.x 无法读取yml配置值的问题:Could not resolve placeholder xxx value '${xxx}'

    最近在用Springboot2.1 新建demo工程的时候,在DataSourceConfig类中通过 @Value("${spring.datasource.url}") 的方式 ...

  4. Python中的xxx == xx是否等价于xxx is xxx

    先上代码: >>> a = 1 >>> b = 1 >>> a is b True >>> a == b True what? ...

  5. Python中的xxx+=xxx和xxx=xxx+xxx一些区别及执行过程

    预知小知识: Python中的变量与其他语言稍有差异,如a = 10并不是直接在内存中创建一个变量a其值为10,而是在内存中创建一个a这个a指向这个10,在Python中所有牵扯到等号的均不是值赋值, ...

  6. 模块,import,from xxx import xxx

    一,模块 模块就是一个包含了python定义和声明的文件,文件名就是模块的名字加上.py后缀,总体来说,import加载的模块一共分成四个通用的类别: 1,使用python编写的py文件 2,已被变异 ...

  7. hadoop报错:java.io.IOException(java.net.ConnectException: Call From xxx/xxx to xxx:10020 failed on connection exception: java.net.ConnectException: 拒绝连接

    任务一直报错 现象比较奇怪,部分任务可以正常跑,部分问题报错 报错信息如下: Ended Job = job_1527476268558_132947 with exception 'java.io. ...

  8. Invalid HTTP_HOST header: 'xxx.xx.xxx.xxx:8000'. You may need to add 'xxx.xx' to ALLOWED_HOSTS

    Invalid HTTP_HOST header: 'xxx.xx.xxx.xxx:8000'. You may need to add 'xxx.xx' to ALLOWED_HOSTS - buk ...

  9. 命令“"xxx.exe" xxx”已退出,代码为 n。这些错误是什么意思?(3 / 123 / 9009)

    命令“”xxx.exe” xxx”已退出,代码为 n. 我们在 cmd 中输入常见命令的时候,如果命令输入错误或使用错误,cmd 中会提示错误原因,帮助我们定位并解决问题.然而如果相同的命令放到了 V ...

随机推荐

  1. How to use STA(sql tuning advisor)

    一.手工生成Sql tuning advisor  1.SQL text format: DECLARE   my_task_name VARCHAR2(30);   my_sqltext   CLO ...

  2. elf格式分析

    近期研究了一下elf文件格式,发现好多资料写的都比較繁琐,可能会严重打击学习者的热情,我把自己研究的结果和大家分享,希望我的描写叙述可以简洁一些. 一.基础知识 elf是一种文件格式,用于存储Linu ...

  3. VMware中linux与window目录共享

    在虚拟机下来实如今windows下共享一个目录: (前提已安装完毕vmtools:http://blog.csdn.net/pipisorry/article/details/21318931) 打开 ...

  4. A亚马逊WS网上系列讲座——怎么样AWS云平台上千万用户的应用建设

    用户选择云计算平台构建应用程序的一个重要原因是高弹性的云平台和可扩展性. 面向Internet应用程序通常需要支持用户使用大量,但要建立一个高度可扩展.具有一定的挑战,高度可用的应用程序,只有立足AW ...

  5. 公布AppStore被拒绝的经历

    我们知道IOS发布的版本有很多原因是苹果拒绝发表,我总结了这里3手头上做的原因,他拒绝游,包括同事.朋友拒绝的理由,IOS app参考朋友. 1. 使用非公开API该计划将被拒绝 2. beta版.d ...

  6. hdu4487(概率dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4487 题意:开始位置在0,每一步可以向右向左或者不动,问走了n步后,路径中能到达最右的期望. 分析:d ...

  7. Oracle数据库案例整理-Oracle系统执行时故障-Shared Pool内存不足导致数据库响应缓慢

    1.1       现象描写叙述 数据库节点响应缓慢,部分用户业务受到影响. 查看数据库告警日志,開始显示ORA-07445错误,然后是大量的ORA-04031错误和ORA-00600错误. 检查数据 ...

  8. ContentType ,charset和pageEncoding的区别(转)

    ========================说法一=========================== ContentType 属性指定响应的 HTTP 内容类型.如果未指定 ContentTy ...

  9. java7 API详解

    Java™ Platform, Standard Edition 7API Specification This document is the API specification for the J ...

  10. OpenCV两张图片的合并

    转载请注明出处..! http://blog.csdn.net/zhonghuan1992 OpenCV两张图片的合并 原理: 两张图片合并,想想图片是用一个个像素点来存储.每一个像素点有他的值. 那 ...