在 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 循环?
PHP中文网2017-04-17 11:29:56
I found this question and searched a lot. Is the person who asked the question not from SF? Haha, just kidding
{}
. do while
loop, you can use break
to achieve this purpose. goto
, some companies do not allow the use of goto
. 兼容
various compilers. 宏
there will be no errors when unfolding. If you put it directly in 花括号
, it will be wrongThis article is very detailed
大家讲道理2017-04-17 11:29:56
Do while(0) is also useful in macro definition #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;
}
#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;
}
PHP中文网2017-04-17 11:29:56
Block-level scope. Avoid variable names inside {} blocks from spreading into the upper scope. The advantage is that it reduces the number of names that need to be remembered in the outer scope and reduces the possibility of misuse of these variables.
Specifically, in this code, pImage
is restricted to be used only in this block, and cannot be used outside this block to avoid misuse by programmers and avoid name conflicts.
Common in languages that support block-level scoping, such as C++/Java. gcc also supports writing only curly braces:
{
int x = 0;
// do something
}
// can't use x here
{
int x = 1; // another x
// do something
}
// can't use x here
大家讲道理2017-04-17 11:29:56
Another function is to use goto to unify error handling, such as:
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;
}
If you use do{}while(0), it will look like this
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;
}
}
巴扎黑2017-04-17 11:29:56
Do-while is commonly used in macros, such as
#define SAFE_FREE(p) do {free(p);p=NULL;} while(0)
Call this macro in code:
SAFE_FREE(ptr);
Using do-while, the above macro call can look like a "function call", and there can be a semicolon at the end of the sentence
Because do{} while(0);
can have a semicolon at the end and use braces to enclose the statement;
Without do-while, the above macro is written as:
define SAFE_FREE(p) free(p);p=NULL;
When calling, most people will use it like this:
if(条件)
SAFE_FREE(p); // 展开后, p=NULL就不在if控制内了