do {} while(0)的妙用
转自
[https://blog.csdn.net/qq_16777851/article/details/80867981](https://blog.csdn.net/qq_16777851/article/details/80867981](https://blog.csdn.net/qq_16777851/article/details/80867981](https://blog.csdn.net/qq_16777851/article/details/80867981 )
-
避免空的宏定义在声明时出现警告
#define FUNC
#define FUNC do{}while(0)
-
避免出现歧义代码
#define FUN1(x) x=1;x++;
if(...)
FUNC1();
上面宏在使用时,展开后:
if(...)
x = 1;
x++;
有些风格的代码只有一个语句的if会省略{},这样导致了仅x = 1;
受if逻辑控制,与原意违背。但是有人可能针对上面的宏定义做一些改进:
#define FUN1(x) {x=1;x++;}
如果引用出代码是:
if(...)
FUN1(x);
else
xxxx;
展开后会多出一个;
,导致编译不通过。
if(...)
{
x=1;
x++;
} ;
else
xxxx;
如果是用do{}while(0)
,看看展开后的效果
#define FUN1(i) do{i=1;i++}while(0)
if(...)
do{i=1;i++}while(0);
else
xxxx;
语句块恰好被{}
包含,而整个do{}while(0);
又恰好可以看做一个语句,不会出现编译错误。
-
某些情况下避免使用goto语句
int *p_int = NULL:
p_int = malloc(100*sizeof(int)) ;
if(!p_int)
{
return -1;
}
//return 0 suceess
if(!func1())
{
free(p_int);
return -1;
}
//return 0 suceess
if(!func2())
{
free(p_int);
return -1;
}
...
free(p_int);
上面这段代码在申请内存后,在多个出错处理里面要调用free来释放内存,有一种改进方法是使用goto语句,像内核驱动代码通常这样做:
int *p_int = NULL:
p_int = malloc(100*sizeof(int));
if(!p_int) goto err;
//return 0 suceess
if(!func1()) goto err;
//return 0 suceess
if(!func2()) goto err;
...
free(p_int);
return 0;
err:
free(p_int);
return -1;
可以看到,是用goto语句代码简洁了很多,但在代码复杂的一定程度后,有多个goto代码就显得比较乱了。这时候就可以是用do {}while(0)来处理了。(个人感觉和goto差不多,如果出错的处理方式不同,那么显然用goto才可以解决)
int *p_int = NULL:
do
{
p_int = malloc(100*sizeof(int));
if(!p_int) break;
//return 0 suceess
if(!func1()) break;
//return 0 suceess
if(!func2ii) break;
...
free(p_int);
return 0;
}
while(0)
free(p_int);
return -1;
-
提供代码块作用域
可以用于自定义变量,不怕和外面名重复。