今天在阅读linux代码的时候,看到linux很多代码都用了:刚开始以为这是多此一举,既然是while(0),那么写和没写都是一个样。但是在好奇心的驱动下,查阅了许多资料后,发现,这句代码真的是“神”一般的操作,那么它到底有什么作用呢?
一,避免使用goto控制流程:我们在一些函数中,如果在退出前,需要一些清理工作,正常情况下,我们可以使用goto来实现,比如:
int foo()
{
somestruct *ptr = malloc(...);
dosomething...;
if(error)
goto END;
dosomething...;
END:
free(ptr);
return 0;
}
但是由于goto
但是由于goto不符合结构化设计,很多人都不倡导使用,这时候就可以使用do while了:
int foo()
{
somestruct *ptr = malloc(...);
do
{
dosomething...;
if(error)
break;
dosomething...;
} while(0);
free(ptr);
return 0;
}
这里将函数主体部分使用do{...}while(0)包含起来,使用break来代替goto,后续的清理工作在while之后,现在既能达到同样的效果,而且代码的可读性、可维护性都要比上面的goto代码好的多了。
二.避免宏定义的一些编译或者错误:我们假设定义一个宏:
#define DELETE_IT(p) delete p; p = NULL;
那么在下面的代码中:
If(NULL!=p)
DELETE_IT(p)
else
.......
宏会被展开成:
If(NULL!=p)
delete p; p=NULL;
else
........
那么就存在两个问题:
1,编译错误:因为if分支后面有两个语句,导致else分支没有对应的if
2,逻辑错误:假设没有else分支,则SAFE_FREE中的第二个语句无论if测试是否通过,都会执行,这个就很严重
那么有什么办法解决这个问题吗?答案是有,do while就是用来解决这个问题的:
#define DELETE_IT(p) do { delete p; p=NULL; } while(0);
这样定义,展开后,就变成:
If(NULL!=p)
do { free(p); p=NULL; } while(0);
else
.......
这样就可以避免上面的问题了
即学即用的技巧,可以在代码秀一下了
,