今天在阅读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 .......
这样就可以避免上面的问题了
即学即用的技巧,可以在代码秀一下了