- 确保宏展开不会出错
- 代替goto
- 避免由宏引起的警告
- 定义单一的函数块来完成复杂的操作
do...while通常是用来做循环用的,但经常看到一些开源代码会出现do...while(0)这样的代码,利用该代码段会将执行体 内的代码先执行一遍的特性,为什么要这样用呢?确保宏展开不会出错
========》define的使用《========
使用do{...}while(0)构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。
=================================================修正前=================================================
#define func(x) func1(x); func2(x)
// 使用时,由于if只有下一条语句时,可不加{}
if (...)
func(10);
// 但此时会出现漏洞,代码被替换后,将不会按预期运行
if (...)
func(10);
func(10);
=================================================修正后=================================================
#define func(x) do { func1(x); func2(x); } while (0)
if (...)
func(10);
// 即可正常运行
if (...)
do { func1(10); func2(10); } while (0)
另外,若给他加上{}
=================================================修正前=================================================
#define func(x) { func1(x); func2(x); }
if(...)
func(x);
// 代码替换后,将多出一个分号
if(...)
{ func1(x); func2(x); };
=================================================修正后=================================================
#define func(x)
do {
func1(x);
func2(x);
}while(0);
代替goto
避免使用goto语句,并消除代码冗余;
bool Execute()
{
// 分配资源
int *p = new int;
bool bOk(true);
// 执行并进行错误处理
bOk = func1();
if(!bOk) goto errorhandle;
bOk = func2();
if(!bOk) goto errorhandle;
bOk = func3();
if(!bOk) goto errorhandle;
// ..........
// 执行成功,释放资源并返回
delete p;
p = NULL;
return true;
errorhandle:
delete p;
p = NULL;
return false;
}
=================================================修正后=================================================
bool Execute()
{
// 分配资源
int *p = new int;
bool bOk(true);
do
{
// 执行并进行错误处理
bOk = func1();
if(!bOk) break;
bOk = func2();
if(!bOk) break;
bOk = func3();
if(!bOk) break;
// ..........
}while(0);
// 释放资源
delete p;
p = NULL;
return bOk;
}
避免由宏引起的警告
由于内核不同体系结构的限制,我们可能需要多次使用空宏。在编译的时候,这些空宏会产生警告,为了避免这种警告,我们可
以使用do{...}while(0)来定义空宏,这样在编译的时候就不会产生警告;
#define EMPTYMCRO do{}while(0)
定义单一的函数块来完成复杂的操作
如果你有一个复杂的函数且你不想要创建新的函数,那么使用do{...}while(0),你可以将一些代码放在这里面并定义一些变量,这样
你就不必担心do{...}while(0)外面的变量名是否与do{...}while(0)里面的变量名相同造成重复了。



