1

In the tutorial of Nextpeer you can see such code:

CCScene* GameLayer::scene() {
    CCScene * scene = NULL;
    do {
        // 'scene' is an autorelease object
        scene = CCScene::create();
        CC_BREAK_IF(! scene);

        // 'layer' is an autorelease object
        GameLayer *layer = GameLayer::create();
        CC_BREAK_IF(! layer);

        // add layer as a child to scene
        scene->addChild(layer);
    } while (0);

    // return the scene
    return scene;
}

What is the meaning of do-while block in this code?

Narek
  • 38,779
  • 79
  • 233
  • 389
  • 1
    It's there so you can execute the loop at most once while keeping a single return statement and without using `goto`. Especially in this function, screw the loop and just use `return`. – chris Nov 10 '14 at 19:30
  • 3
    I'm curious what the definition of `CC_BREAK_IF` is. If it is literally just `#define CC_BREAK_IF(x) if (x) break;` then someone needs to be hit with the clue-by-four. – cdhowie Nov 10 '14 at 19:33
  • 2
    @cdhowie This is a first. A macro that is *longer* than the code it produces. Brilliant. – Barry Nov 10 '14 at 19:53
  • @Barry Indeed, all it really does is put the action before the conditional, presumably out of some misguided notion that it reads better. Similar to the Perl construct `x if y;` but at least there it's *part of the language* and therefore expected. – cdhowie Nov 10 '14 at 19:58
  • I think the macro can be defended since it's one of a collection of similar macros for error handling. I've seen this pattern of error handling used in other projects. – Michael Burr Nov 10 '14 at 20:45

4 Answers4

5

CC_BREAK_IF is a macro for if(condition) break. (Edit: I've confirmed that it is.)

This is an idiom used for a structured goto:

do {
    if (!condition0) break;
    action0();
    if (!condition1) break;
    action1();
} while(0);

do...while(0); exists only to allow a break statement to skip some section of code.

This would be similar to:

if (!condition0) goto end;
action0();
if (!condition1) goto end;
action1();
end:

Except it avoids the use of goto.

The use of either of these idioms is to avoid a nested if:

if (condition0) {
    action0();
    if (condition1) {
        action1();
    }
}
Radiodef
  • 37,180
  • 14
  • 90
  • 125
2

In C and C++ the break statement works only in select contexts: a while, do/while or for loop or in a switch statement. The CC_BREAK_IF macro presumably executes a break if the condition is met. This is a simple method for handling exceptional/error conditions in C (a poor man's exception handling, if you will).

The do/while loop that never loops simply provides a context for the break statements to work.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
1

The meaning is to make CC_BREAK_IF statements work correctly, that is to break the loop and jump to return scene;.

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
0

It's a common method when you have several conditional statements which would otherwise result in a chain of if/else clauses. Instead you use a single iteration loop and use break statements to exit the loop (CC_BREAK_IF is probably a macro which tests an expression and break if true).

Paul R
  • 208,748
  • 37
  • 389
  • 560