最近发现很多代码在进行宏定义的时候使用喜欢使用
#define MACRO_NAME(para) do{macro content}while(0)
的格式,总结了以下几个原因:
 
1,空的宏定义避免warning:
#define foo() do{}while(0)
 
2,存在一个独立的block,可以用来进行变量定义,进行比较复杂的实现。
 
3,如果出现在判断语句过后的宏,这样可以保证作为一个整体来是实现:
#define foo(x) \
action1(); \
action2();
在以下情况下:
if(NULL == pPointer)
   foo();
就会出现action1和action2不会同时被执行的情况,而这显然不是程序设计的目的。
 
4,以上的第3种情况用单独的{}也可以实现,但是为什么一定要一个do{}while(0)呢,看以下代码:
#define switch(x,y) {int tmp; tmp=x;x=y;y=tmp;}
if(x>y)
switch(x,y);
else       //error, parse error before else
otheraction();
 
在把宏引入代码中,会多出一个分号,从而会报错。
其实,这种用法要根据自己的习惯,有的人不习惯在调用宏代码后加上“;”,也有的喜欢,不过,只要在判断语句之后记得加上{}就可以保证不出错了。

为什么使用do{}while(0)来进行宏定义的更多相关文章

  1. typedef 类型重命名 和 #define 宏定义(1)

    http://www.blogjava.net/jasmine214--love/archive/2010/11/29/339307.html 在现实生活中,信息的概念可能是长度,数量和面积等.在C语 ...

  2. C语言中的宏定义

    目录(?)[-] 简单宏定义 带参数的宏 运算符 运算符 宏的通用属性 宏定义中圆括号 创建较长的宏 较长的宏中的逗号运算符 宏定义中的do-while循环do 空操作的定义 预定义宏 C语言中常用的 ...

  3. 宏定义(无参宏定义和带参宏定义),C语言宏定义详解

    1.宏定义说明 宏定义是比较常用的预处理指令,即使用"标识符"来表示"替换列表"中的内容.标识符称为宏名,在预处理过程中,预处理器会把源程序中所有宏名,替换成宏 ...

  4. C/C++ 宏定义

    宏定义(无参宏定义和带参宏定义) 宏定义是比较常用的预处理指令,即使用"标识符"来表示"替换列表"中的内容.标识符称为宏名,在预处理过程中,预处理器会把源程序中 ...

  5. 函数式宏定义用do...while(0)的好处

    函数式宏定义经常写成这样:<pre lang="c" escaped="true">#define device_init_wakeup(dev, ...

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

    最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总结了一下讨论,加上自己的理解,do{...}while(0)的价值 ...

  7. 宏定义中使用do{}while(0)的好处 (转载)

    宏定义中使用do{}while(0)的好处   #define MACRO_NAME(para) do{macro content}while(0)   的格式,总结了以下几个原因:   1,空的宏定 ...

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

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

  9. do {...} while (0) 在宏定义中的作用

    如果你是一名C程序员,你肯定很熟悉宏,它们非常强大,如果正确使用可以让你的工作事半功倍.然而,如果你在定义宏时很随意没有认真检查,那么它们可能使你发狂,浪费N多时间.在很多的C程序中,你可能会看到许多 ...

随机推荐

  1. java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

    微信小程序前后台使用get方式传参时报错如图.但在微信开发平台和苹果测试都没事,在安卓手机上就报这个错,猜想原因是get传递了汉字的原因. 尝试了下在后台输出从前台获取的参数,但是后台什么也没有获取到 ...

  2. 多进程编程之守护进程Daemonize

    1.守护进程 守护进程(daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务.很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭.另一些只在需要的时候才启动,完成任务后就自动结束. ...

  3. BZOJ3252 攻略(贪心+dfs序+线段树)

    考虑贪心,每次选价值最大的链.选完之后对于链上点dfs序暴力修改子树.因为每个点最多被选一次,复杂度非常正确. #include<iostream> #include<cstdio& ...

  4. 五种并发包总结ConcurrentHashMap CopyOnWriteArrayList ArrayblockingQueue

    五种并发包总结 1.常用的五种并发包 ConcurrentHashMap CopyOnWriteArrayList CopyOnWriteArraySet ArrayBlockingQueue Lin ...

  5. 【转】VMware虚拟机三种网络模式详解

    由于Linux目前很热门,越来越多的人在学习Linux,但是买一台服务放家里来学习,实在是很浪费.那么如何解决这个问题?虚拟机软件是很好的选择,常用的虚拟机软件有VMware Workstations ...

  6. Java之IO流(字节流,字符流)

    IO流和Properties IO流 IO流是指计算机与外部世界或者一个程序与计算机的其余部分的之间的接口.它对于任何计算机系统都非常关键, 因而所有 I/O 的主体实际上是内置在操作系统中的.单独的 ...

  7. spark 调优——基础篇

    开发调优 调优概述 Spark性能优化的第一步,就是要在开发Spark作业的过程中注意和应用一些性能优化的基本原则.开发调优,就是要让大家了解以下一些Spark基本开发原则,包括:RDD lineag ...

  8. 解题:ZJOI 2015 幻想乡战略游戏

    题面 神**所有点都爆int,我还以为我写出什么大锅了,不开long long见祖宗... 动态点分治利用点分树树高不超过log的性质,我们对每个点维护一个子树和,一个点分树子树和,一个点分树上父亲的 ...

  9. 解题:CF1009 Dominant Indices

    题面 长链剖分模板题 只能按深度统计,同时比DSU on tree难理解一些,但是复杂度少个log 对每个点抓出向下延伸最长的儿子叫做长儿子.在合并时用指针继承信息,对于长儿子O(1)继承,其他儿子暴 ...

  10. RF - 完整用例展示

    将重复性动作进行封装为keyword,在测试用例中调用keyword. *** Settings *** Documentation Simple example using SeleniumLibr ...