1. 帮助定义宏
在看redis源码时,发现很多宏都用了do{…}while(0),例如在zmalloc.c中用于统计内存使用量时的宏:
#define update_zmalloc_stat_add(__n) do { \
pthread_mutex_lock(&used_memory_mutex); \
used_memory += (__n); \
pthread_mutex_unlock(&used_memory_mutex); \
} while(0)
#define update_zmalloc_stat_sub(__n) do { \
pthread_mutex_lock(&used_memory_mutex); \
used_memory -= (__n); \
pthread_mutex_unlock(&used_memory_mutex); \
} while(0)
如果不用do{…}while(0)会怎么样?以下面的代码为例:
#define swap(a,b) do{ a+=b; b=a-b; a=a-b; }while(0)
int main()
{
int i=0;
int j=100;
if(i<j)
swap(i,j);
}
展开后的实际代码:
int main()
{
int i=0;
int j=100;
if(i<j)
do{ i+=j; j=i-j; i=i-j; }while(0);
}
这是没有问题的,如果我们不用do{…}while(0),看看会是什么效果:
#define swap(a,b) a+=b; b=a-b; a=a-b;
int main()
{
int i=10;
int j=100;
if(i<j)
swap(i,j);
}
展开后:
int main()
{
int i=10;
int j=100;
if(i<j)
i+=j; j=i-j; i=i-j;
}
改变了原来的函数本来的意义(这个例子结果是一样的,举例不好)。
如果加上{}又会是什么效果,这次加上一个else:
#define swap(a,b) {a+=b; b=a-b; a=a-b;}
int main()
{
int i=10;
int j=100;
if(i<j)
swap(i,j);
else{ /*code*/ }
}
展开后,是错误代码,else找不到if,因为大括号后不能接“;”:
int main()
{
int i=10;
int j=100;
if(i<j)
{i+=j; j=i-j; i=i-j;};
else{ /*code*/ }
}
2. 替换goto
int main()
{
int i=0;
/*code*/
do
{
/*code*/
if(i<0) break;
/*code*/
if(0==i) break;
/*code*/
}while(0)
/*code*/
}
while(0){…}也有这个效果。