在 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
發現這個問題一搜一大堆哦,題主確定不是SF的托麼,哈哈,開個玩笑
{}
更直觀些。 do while
循環中,則能用break
達到這個目的。 goto
,有些公司不讓用goto
。 兼容
各種編譯器。 宏
展開的時候不會出錯。如果直接放在花括号
裡會出錯的這篇文章很詳細
大家讲道理2017-04-17 11:29:56
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;
}
#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
區塊級作用域。避免 {} 區塊裡面的變數名稱擴散到上層作用域。好處是減少外層作用域中需要記憶的名字的數量,減少誤用這些變數的可能性。
具體來說,這段程式碼中 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
大家讲道理2017-04-17 11:29:56
另外一種作用是這樣的使用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;
}
}
巴扎黑2017-04-17 11:29:56
在巨集中常用do-while, 例如
#define SAFE_FREE(p) do {free(p);p=NULL;} while(0)
在程式碼裡呼叫這個巨集:
SAFE_FREE(ptr);
用do-while, 上面的宏呼叫可以看起來像"函數呼叫", 句尾可以有分號
因為do{} while(0);
最後可以帶分號, 並且利用大括號把語句括起來;
加入不用do-while, 上面的宏就寫成:
define SAFE_FREE(p) free(p);p=NULL;
呼叫的時候一般人會這麼用:
if(条件)
SAFE_FREE(p); // 展开后, p=NULL就不在if控制内了