首页 > 代码库 > do{...}while(0)用法总结

do{...}while(0)用法总结

1、消除冗余代码以及避免微妙的goto语句:

通常,如果一个函数开始要分配一些资源,然后如果在中途遇到错误则要退出函数,当然,退出前要释放资源

一般写法:

 1 int InitSomething() 2 { 3     char* pImage = NULL; 4     char* pBitMap = NULL; 5     char* pBuffer = NULL; 6  7     pImage = (char*)malloc(10); 8     if(pImage == NULL) 9     {10         return -1;11     }12 13     pBitMap = (char*)malloc(20);14     if (NULL == pBitMap)15     {16         free(pImage);17         return -1;18     }19     20     pBuffer = (char*)malloc(1024);21     if(NULL == pBuffer)22     {23         free(pImage);24         free(pBitMap);25         return -1;26     }27 28     ....29 30 31     free(pImage);32     free(pBitMap);33     free(pBuffer);34 35     return 0;36 }
View Code

goto语句写法:

 1 int InitSomething() 2 { 3     char* pImage = NULL; 4     char* pBitMap = NULL; 5     char* pBuffer = NULL; 6  7     pImage = (char*)malloc(10); 8     if(pImage == NULL) 9     {10         goto ret;11     }12 13     pBitMap = (char*)malloc(20);14     if (NULL == pBitMap)15     {16         goto ret;17     }18     19     pBuffer = (char*)malloc(1024);20     if(NULL == pBuffer)21     {22         goto ret;23     }24 25     ....26 27     return 0;28 ret:29     if (pImage)30     {31         free(pImage);32     }33 34     if (pBitMap)35     {36         free(pBitMap);37     }38 39     if (pBuffer)40     {41         free(pBuffer);42     }43 44     return -1;45 }
View Code

do...while(0)优化写法:

 1 int InitSomething() 2 { 3     char* pImage = NULL; 4     char* pBitMap = NULL; 5     char* pBuffer = NULL; 6     int nRet = 0; 7  8     do 9     {10         pImage = (char*)malloc(10);11         if(pImage == NULL)12         {13             nRet = -1;14             break;15         }16 17         pBitMap = (char*)malloc(20);18         if (NULL == pBitMap)19         {20             nRet = -1;21             break;22         }23         24         pBuffer = (char*)malloc(1024);25         if(NULL == pBuffer)26         {27             nRet = -1;28             break;29         }30     }while(0);31 32     if (nRet != 0)33     {34         if (pImage)35         {36             free(pImage);37         }38 39         if (pBitMap)40         {41             free(pBitMap);42         }43 44         if (pBuffer)45         {46             free(pBuffer);47         }48         return -1;49     }50 51     ....52 53     return 0;54 }
View Code

2、消除空声明在编译时出现警告:

#define FOOBAR do { } while(0)

3、消除代码块误用而产生的编译或运行时的错误:

#define swap(x,y) { int tmp; tmp=x; x=y; y=tmp; }if (x > y)    swap(x,y);else      dosth();编译后预处理器替换的代码如下:if (x > y)    { int tmp; tmp=x; x=y; y=tmp; };else//变成了悬空分支    do_something();错误出在分号“;”直接位于代码块的后面,解决的办法:宏定义嵌到do...while(0):#define swap(x,y) do { int tmp; tmp=x; x=y; y=tmp; } while(0)宏展开后的代码如下:if (x > y)    do { int tmp; tmp=x; x=y; y=tmp; } while(0);else    do_something();

4、消除条件语句中使用宏的隐患:

#define FOOBAR(x) \    printf("parameter is %s\n", x);     do_sth(x)如下代码片段if (name == 2)    FOOBAR("tcp");宏展开后:if (name == 2)    printf("parameter is %s\n", "tcp");do_sth("tcp");但实际上:if语句只作用于printf(), do_sth() 没按照原有意图一起受到条件的控制重新定义宏:#define FOOBAR(x) do{     printf("parameter is %s\n", x);     do_sth(x);}while(0)代码片段展开:if (name == 2)    do{printf("arg is %s\n", "tcp"); do_sth("tcp");} while (0);