您的位置:首页 > 其它

关于do{...}while(FALSE);

2014-05-19 23:41 239 查看
今天看MFC的代码,无意中发现这样一种用法,当时觉得都do了,为什么接false啊,这样不就等于干执行一遍么?虽然大括号内恰好有什么改变XXX为true或者false的语句,但是while(FALSE)明显没用到那个变量。为什么多此一举,肯定不能那么简单,于是就查了一下,发现不光解释很多,争议也很多。

首先是这种语句可以顶替goto,而goto是不提倡用的(就不提某Turing Award winner和他的PASCAL之类的话题了,和我无关):

do{
if(condition1)
break;
if(condition2)
break;
.....
return;
}while(FALSE);
...
相应的goto用法:

if(condition1)
goto label;
if(condition2)
goto label;
....
return;
label:
........


都是随便一种条件就跳到最后,等于一个互斥操作

有人觉得下面这种更好:

if(!condition1&&!condition2&&......){return;}
显然他被个案迷惑了,没有想过什么叫通用性、灵活性和耦合性,不知道下边这种情况他怎么解决:

do{
if(condition1){
printf("condition1!");
break;
} if(condition2){
printf("condition2!");
 break;
}.....
return;
}while(FALSE);
...

不要以为这很幼稚,我看的代码真的就加了类似语句,发error message之类的。

也就是说,do{...}while(0); 可以实现类似 try{...}catch{}; 的功能。

有很多人强调:do{...}while(0); 主要是给宏定义用的。如下:

#define SAFE_DELETE(p) do{delete p;p = NULL}while(0);
//如果去掉do{}while(0);
#define SAFE_DELETE(p) delete p;p=NULL;
//那么诸如:
if(NULL != p) SAFE_DELETE(p)
else ..do sth...
//就会出现两个问题:
//1)if分支后有两个statement,导致else分支没有对应的if语句,编译错误。
//2)if后边跟两个语句,没有大括号,第二个语句必然永远都能执行。
但是个人觉得“天空飘来五个字,这都不算事儿”:

#define SAFE_DELETE(p) {delete p;p = NULL;}
这样不就完了?

大括号不大括号和do...while(); 没有直接联系吧?等验证一下~~~~

另外do{...}while(0); 还能缓解(某些情况)的多重嵌套。

比如用:

do{
if(!condition1)
break;
if(!condition2)
break;
do sth;
}while(FALSE);
代替:

if(condition1){
if(condition2){
do sth;
}
}
(为偷懒,少写基层~)

MFC中的例子:

#define AFXASSUME(cond) do{bool _afx_condVal = !!(cond);ASSERT(_afx_condVal);_analysis_assume(_afx_condVal);}while(0);
由此容易看出另外一个好处,就是宏定义有很多行的时候,大家都号称能起到保护作用(我经验浅,看的不是很直观)

还有我看的几段代码,没打开,也不贴了。

此外,《Linux设备驱动开发详解》3.5.3中应该有讲,这个是Linux内核中常用的方法,不要再说这种方法很少见很低级了~~~~~

MARK:有人说goto也挺好用的,他们公司用,没多少问题。有人讽刺他们公司都是高手,这么晦涩的代码都不出错。有人说用longjmp害死他,我也不懂这个longjmp。

PS:宏定义中的空格问题?我都忘得差不多了,没印象了,p = NULL这种有空格的应该没错吧,应该该行字符串有多长就定义多长?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: