do { }while(0)的妙用

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.一些复杂的宏的实现。

    .....


猜你喜欢

转载自blog.csdn.net/qq_16777851/article/details/80867981