zoukankan      html  css  js  c++  java
  • 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
    ", x); 
        do_sth(x)
    
    如下代码片段
    if (name == 2)
        FOOBAR("tcp");
    
    宏展开后:
    if (name == 2)
        printf("parameter is %s
    ", "tcp");do_sth("tcp");
    
    但实际上:if语句只作用于printf(), do_sth() 没按照原有意图一起受到条件的控制
    
    重新定义宏:
    #define FOOBAR(x) 
    do{ 
        printf("parameter is %s
    ", x); 
        do_sth(x);
    }while(0)
    
    代码片段展开:
    if (name == 2)
        do{printf("arg is %s
    ", "tcp"); do_sth("tcp");} while (0);
  • 相关阅读:
    设计模式之八:外观模式(Facade)
    Python模块学习笔记— —time与datatime
    Android加载图片OOM错误解决方式
    [C#]Attribute特性(2)——方法的特性及特性参数
    [C#]Attribute特性
    [Winform]一个简单的账户管理工具
    [C#]AES加密算法实现
    [C#基础]ref和out的区别
    [Socket网络编程]一个封锁操作被对 WSACancelBlockingCall 的调用中断。
    [Socket网络编程]由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
  • 原文地址:https://www.cnblogs.com/eric-geoffrey/p/3822675.html
Copyright © 2011-2022 走看看