do{...}while(0)用法总结
1、消除冗余代码以及避免微妙的goto语句:
通常,如果一个函数开始要分配一些资源,然后如果在中途遇到错误则要退出函数,当然,退出前要释放资源
一般写法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
goto语句写法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
do...while(0)优化写法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
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);
posted on 2014-07-03 16:32 eric.geoffrey 阅读(460) 评论(0) 编辑 收藏 举报