- 前言
- do..while(0)的优点
- do..while(0)的由来
- 结语
前言
在C/C++中,do...while 通常是用来做循环用的,然而我们做循环操作可能用for和while要多一些。经常看到Linux内核代码会出现do...while(0)这样的代码。如内核里的:
#define READ_NEXT_PAIR(v1, v2, i) do { if (i+2 >= ArrayLen) break; i += 2; v1 = Array[i]; v2 = Array[i+1]; } while(0)
这样的代码肯定不是用来做循环,那么do...while(0)的作用是?
辅助定义复杂的宏,避免引用的时候出错,提高代码健壮性
本篇就来介绍do...while(0)的具体用法和使用原因
do..while(0)的优点
当我们看到上面那个宏定义非常复杂,我们自然而然地会想到,为啥不让他变成一个函数呢?在宏定义里面搞的这么多语句,不如直接定义一个函数来的方便。但是如果使用函数的话,就会有函数调用压栈出栈开销。宏编译的时候会展开基本没有开销。还有就是避免引用的时候出错
do..while(0)的由来
假设你需要定义一个这样的宏:
#define DOSOMETHING()\
func1();\
func2();
这个宏的本意是,当调用DOSOMETHING()时,函数func1()和func2()都会被调用。但是如果你在调用的时候这么写:
if(a>0)
DOSOMETHING();
宏在预处理的时候会直接被展开,你实际上写的代码是这个样子的:
if(a>0)
func1();
func2();
这就出现了程序逻辑上的问题,因为无论a是否大于0,func2()都会被执行,导致程序出错。 那么仅仅使用{}将func1()和func2()包起来行么?我们来试试
#define DOSOMETHING(){\
func1();\
func2();}
...
if(a>0)
DOSOMETHING();
else
...
...
宏展开后,代码如下所示:
#define DOSOMETHING(){\
func1();\
func2();}
...
if(a>0)
{
func1();
func2();
};
else
...
...
这样是不会编译通过,所以,很多人才采用了do{...}while(0)
#define DOSOMETHING(){\
do{ \
func1();\
func2();}
}while(0);
...
if(a>0)
DOSOMETHING()
else
...
...
这样的处理不仅解决上述if语句所带来的问题,而且让程序更加美观
结语
相信大家对内核do...while(0)的语法有所了解,如果我的文章对你有所收获的话,可以点赞关注转发给你小伙伴们
本文由 mdnice 多平台发布