do { }while(0)的妙用
程序员文章站
2024-03-23 13:59:34
...
1.避免空的宏定义在声明时出现警告。
#define FUNC
#define FUNC do{}while(0)
2.避免出现歧义代码
#define FUN1(x) x=1;x++;
if(...)
FUNC1();
else
FUNC2();
上面的宏展开后就成了下面这样,很明显和写代码时的语义不符。
if(...)
x=1;x++;
else
FUNC2();
通常我们的做法是给宏加上大括号。
#define FUN1(x) {x=1;x++;}
我对其做一下简单排版,可以很明显展开后会发现,多了一个";"这很明显是一个错误的语句了,因为if不成立 的情况是一个";",没有了和else配对的if了
if(...)
{
x = 1; x++;
}
;
else
FUNC2();
这个时候用do{ }while(0)就比较符合。
if(...)
do
{
x = 1; x++;
}while(0);
else
FUNC2;
当然,这里建议FUNC2也是用相同的语句。
3.某些情况下避免是用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);
因为C语言没错误处理机制自能自己实现,这里只是举了一个free的例子,如果有多个malloc,上面的错误处理将会更冗余,这里是用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)来处理了。
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;
4.提供代码块作用域
可以用于自定义变量,不怕和外面名重复。
5.一些复杂的宏的实现。
.....