Thanks a lot for all your hard work on this! In coordination with the book “Learn cocos2d 2” and the tutorials, I’m starting to get the hang of it. I just got the HelloCpp and TestCpp applications running on my Android tablet. This was a big step for me because I’m using Ubuntu Linux but had some build errors to sort through in Eclipse due to using a 64-bit OS. Anyhow, I’m just curious about something. I’ve seen ‘do { … some code … } while(0);’ frequently in the cocos2d framework code. Why surround code with this when it doesn’t do anything?
Good question! I’m glad that you notice this.
It’s a practice of Defensive Programming
In my early projects, I used to write code like this
#check(ret) if(!ret) goto cleanup;
bool foo(char* p1, int* p2)
{
// local variable declaration
bool bRet = false; // init all local variables here, assume everything is wrong
int* ptr = NULL;
PROFILER_START();
// check input params
check(p1 && p2);
// start our affairs
bRet = createSomething();
check(bRet); // jump to clean up phase if anything failed
bRet = initSomething()
check(bRet); // the same, check it
// the mem in heap is only alloced in some conditions
if (cond)
{
ptr = (int*)mallc(123123243);
}
bRet = doSomething(ptr);
check(bRet);
bRet = true;
cleanup:
// start clean up phase
if (ptr)
{
delete ptr;
ptr = NULL;
}
if (!bRet)
{
reserveSomething();
}
// So we haven't missed anything until here.
// Make sure the local variables are cleaned, especially the pointer's are deleted.
// A function should have only one return point!
// In this way, it's very easy to add profiler into each function, only one line at start and one at the end.
PROFILER_STOP();
return bRet;
}
We have a cleanup phase and make sure each local variables are ok, they won’t make memory leak. Also make sure some must-be logics for failure will be run.
Each function has only one return point, that is very important. It will make code review easier, and adding profilers are easier too. I think no one like to add profiler like this
bool foo()
{
PROFILER_START();
if (condition1 && condition2)
{
PROFILER_STOP();
return true;
}
else if (condition3)
{
if (condition4)
{
PROFILER_STOP();
return true;
}
else
{
PROFILER_STOP();
return false;
}
}
// Are you sure you have return value for each condition cases? Code reviewer will kick your ass.
}
So far, the defensive programming work ok in C/C++. Then we meet another problem, scripting languages has no “goto” instruction.
That’s why do {} while(0) is here. We use “break” instruction to do the job of jummping.