欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

do { }while(0)的妙用

程序员文章站 2024-03-23 13:59:34
...

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

    .....