do-while-zero 结构在宏定义中的应用
来源:互联网 发布:南京市软件定制开发 编辑:程序博客网 时间:2024/05/16 07:14
do while 语句在使用宏定义时是一个有用的技巧,说明如下:
假设有这样一个宏定义
#define macro(condition) /
if(condition) dosomething()
现在在程序中这样使用这个宏:
if(temp)
macro(i);
else
doanotherthing();
一切看起来很正常,但是仔细想想。这个宏会展开成:
if(temp)
if(condition) dosomething();
else
doanotherthing();
这时的else不是与第一个if语句匹配,而是错误的与第二个if语句进行了匹配,编译通过了,但是运行的结果一定是错误的。
为了避免这个错误,我们使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。
因为在C语言中对宏是不进行语法检查的,所以在替换时有可能产生一些隐蔽的错误,上面举出了一例,再举一例:
#define INTI_RECT_VALUE( a, b )\
a = 0;\
b = 0;
使用宏时,
for (index = 0; index < RECT_TOTAL_NUM; index++)
INTI_RECT_VALUE( rect.a, rect.b );
此时,宏定义的语句并未正确的纳入for循环中,因此,在使用宏定义多条语句时,有必要加一些“封装”措施,比如我们可以这样定义,
#define INTI_RECT_VALUE( a, b )\
{\
a = 0;\
b = 0;\
}
但这样使用时也有一个问题,就是我们不能再宏定义语句后面自然的加一个分号,“{ } ;”的形式在语法上是错误的。而定义成do-while-zero 结构的话,就可以避免这个问题。
所以要写一个包含多条语句的宏的话,使用do-while-zero 结构是保证安全性的一个重要技巧。
在MISRA C-2004中,肯定了这种结构的必要性,以下是其对使用宏定义的规则:
规则19.4 (强制): C的宏只能扩展为用大括号括起来的初始化、常量、小括号括起来的
表达式、类型限定符、存储类标识符或do-while-zero 结构。
这些是宏当中所有可允许使用的形式。存储类标识符和类型限定符包括诸如 extern 、static
和const这样的关键字。使用任何其他形式的#define 都可能导致非预期的行为,或者是非常难
懂的代码。
特别的,宏不能用于定义语句或部分语句,除了do-while 结构。宏也不能重定义语言的
语法。宏的替换列表中的所有括号,不管哪种形式的 ()、{} 、[] 都应该成对出现。
do-while-zero 结构(见下面的例子)是在宏语句体中唯一可接受的具有完整语句的形式。
do-while-zero 结构用于封装语句序列并确保其是正确的。
注意:在宏语句体的末尾必须省略分号。
- do-while-zero 结构在宏定义中的应用
- do...while(0) 在宏定义中的应用
- do while(0)在宏定义中的应用
- do while(0)在宏定义中的应用
- do while(0)在宏定义中的应用
- 宏定义中的do while
- do{}while(0)在宏定义中的作用
- do-while-0-在宏定义中的作用
- do while(0) 在宏定义中的重要用途
- do {...} while (0) 在宏定义中的作用
- do {...} while (0) 在宏定义中的作用
- do...while(0)在宏定义中的巧妙用法
- do...while(0)在宏定义中的用法
- do {...} while (0) 在宏定义中的作用
- do {...} while (0) 在宏定义中的作用
- do {...} while (0) 在宏定义中的作用
- do...while(0)在宏定义中的巧妙用法
- do {...} while (0) 在宏定义中的作用
- C++语法基础--泛型算法(generic algorithm)--只读算法accumulate(),find_first_of(),count(),count_if()
- Java内部类总结
- from表单中的Enctype=multipart/form-data
- 加速编码的17款最棒的CSS工具
- Win32学习笔记——文字和字体
- do-while-zero 结构在宏定义中的应用
- 黑马程序员_IO流——操作基本数据类型的流对象DataStream
- __EMIT伪指令
- java书籍
- MFC图像处理-图像移动显示算法
- C# 解决datatable想删除不想要的多行方法
- uboot启动阶段修改启动参数方法及分析
- hadoopCDH4.1+zookeeperCDH4.1+hbaseCDH4.1环境搭建
- Linux下jdk1.6的安装(经测试,已成功。。。)