#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. 不断摸索发现用 andy 模拟器很不错,感觉跟真机差不多

    嗯,今天也遇到了模拟的问题.那个慢啊,好几分钟才能开机,加载程序总共差不多十几分钟.当时想如果真做android开发必须换电脑啊.后来不断摸索发现用 andy 模拟器很不错,感觉跟真机差不多. 还是真 ...

  2. Hibernate之1-N关联映射

    一.Hibernate之1-N关联映射 1. 哪边是 1 , 哪边是多 ?      须要从业务的角度来说明.比如,Employee 和 Department 之间就是 n-1 的关联关系,Order ...

  3. 4.2、Libgdx每个模块概述

    (原版的:http://www.libgdx.cn/topic/34/4-2-libgdx%E5%90%84%E4%B8%AA%E6%A8%A1%E5%9D%97%E6%A6%82%E8%A7%88) ...

  4. HDU 4704 Sum (费马定理+快速幂)

    Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Subm ...

  5. hdu2066一个人的旅行(dijkstra)

    Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰 ...

  6. Java的byte数组

    今天我们讨论一下Java的byte数组.byte数组就是字节数组,每一位存一个字节.看下面程序,猜猜输出多少? package com.wjy.bytes; import java.io.File; ...

  7. JQuery是继prototype之后又一个优秀的Javascript库

    JQuery是继prototype之后又一个优秀的Javascript库.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器(IE 6.0+, FF 1.5+, Safari 2.0+, Oper ...

  8. hdu2713(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2713 题意:有N个点,每个点都有一个值x,每次进行跳跃,当跳到自己所跳的第奇数个点是+x,第偶数个点时 ...

  9. QT怎样在QTableWidge显示图片

      <span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">QTableWi ...

  10. POJ 1703:Find them, Catch them(并用正确的设置检查)

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 30702   Accepted: ...