do{}while(0) 的作用


cocos2d-x 源码 中,有大量的这种 do{}while(0) 的用法,例如这个:


 do
        {
            CCImage* pImage = new CCImage();
            CC_BREAK_IF(NULL == pImage);
            bRet = pImage->initWithString(text, (int)dimensions.width, (int)dimensions.height, eAlign, fontName, (int)fontSize);
            CC_BREAK_IF(!bRet);
            bRet = initWithImage(pImage);
            CC_SAFE_RELEASE(pImage);
        } while (0);

根据语意,这样写至少保证do后面的代码块执行一次。

这样写的意义是什么?为什么不直接使用块,而一定要加上 do while 循环?

cocos2d-x C++

stupid 10 years, 5 months ago

另外一种作用是这样的使用goto来统一错误处理,如:


 bool foo()
{
    int a, b, c;
    bool ok;
    ok = bar1(&a);
    if (!ok)
        goto failed;
    ok = bar2(&a);
    if (!ok)
        goto failed;
failed:
    process_error();
    return false;
exit:    
    return true;
}

如果配合do{}while(0)的话.会这样的


 bool foo()
{
    int a, b, c;
    bool ok = true;
    do
    {  
        ok = bar1(&a);
        if(!ok)
            break;
        ok = bar2(&b);
        if(!ok)
            break;
    } while(0);
    if (!ok)
    {
        process_error();
        return false;
    }
    else
    {
        return true;
    }
}

无节操的右手 answered 10 years, 5 months ago

发现这个问题一搜一大堆哦,题主确定不是SF的托么,哈哈,开个玩笑

  1. 有时候只是为了代码分块,比仅仅使用 {} 更直观些。
  2. 当你执行一段代码到一半,想跳过剩下的一半的时候,如果你正处于 do while 循环中,则能用 break 达到这个目的。
  3. 变形的 goto ,有些公司不让用 goto
  4. 这样做也可以是 兼容 各种编译器。
  5. 为了 展开的时候不会出错。如果直接放在 花括号 里会出错的

这篇文章很详细哦

青青爱艾艾 answered 10 years, 5 months ago

块级作用域。避免 {} 块里面的变量名扩散到上层作用域中。好处是减少外层作用域中需要记忆的名字的数量,减少误用这些变量的可能性。

具体来说,这段代码中 pImage 就被限制在只能在这个块中使用,出了这个块就不能用了,避免程序员误用,也避免名字冲突。

在 C++ / Java 等支持块级作用域的语言中常见。gcc 还支持只写大括号:


 {
    int x = 0;
    // do something
}
// can't use x here
{
    int x = 1; // another x
    // do something
}
// can't use x here

阿姨洗铁路啊 answered 10 years, 5 months ago

do while(0) 还有个用的地方是在宏定义#define里

不加大括号的代码


 #include <stdio.h>

#define foo(x) int a = x;int b = x;

int main()
{
    int i = 0;
    if (i == 0)
        //无法编译,缺少大括号
        foo(2);
    else
        i = 1;
    return 0;
}

加了大括号的代码


 #include <stdio.h>

//加上大括号
#define foo(x) {int a = x;int b = x;}

int main()
{
    int i = 0;
    if (i == 0)
        //无法编译,后面多了个;号,得把;去了才能编译的过去,和C的语法不怎么协调
        foo(2);
    else
        i = 1;
    return 0;
}

do while(0)的代码


 #include <stdio.h>

#define foo(x) do {int a = x;int b = x;} while(0)

int main()
{
    int i = 0;
    if (i == 0)
        //这下舒服了 xD
        foo(2);
    else
        i = 1;
}

wkj250 answered 10 years, 5 months ago

Your Answer