I use the do { } while (false);
every once in a while when it seems appropriate. I see it as being something like a try/catch block in that I have code that is setup as a block with a series of decisions with possible exceptions and the need is to have the various paths through the rules and logic to merge at the end of the block.
I am pretty sure I only use this construct with C programming and it is not very often.
With the specific example you gave of a series of function calls that will be performed one after the other with the complete series being done or the series stopped if an error is detected, I would probably just use if statements checking an error variable.
{
int iCallStatus = 0;
iCallStatus = doFunc1();
if (iCallStatus == 0) iCallStatus = doFunc2();
if (iCallStatus == 0) icallStatus = doFunc3();
}
This is short and the meaning is straightforward and clear even without comments.
What I have run into from time to time is that this fairly straightforward sequential flow of procedural steps does not apply to a particular requirement. What I need is to create a code block with various decisions, usually involving loops or iterating over some series of data objects and I want to treat this series as a kind of transaction in which the transaction will be committed if there is no error or aborted if there is some kind of an error condition found during the processing of the transaction. As part of this data block, I may create a set of temporary variables for the scope of the do { } while (false);
When ever I use this, I always put a comment indicating that this is a single iteration do while, something like:
do { // single loop code block begins
// block of statements for business logic with single ending point
} while (false); // single loop code block ends
When ever I find myself thinking this construct is necessary, I look to see if the code needs to be refactored or if a function or set of functions would be more appropriate.
The reason I prefer this construct over using a goto
statement is that the use of brackets and indentation makes the source code easier to read. With my editor I can find the top and bottom of the block easily and the indentation makes it easier to visualize the code as a block with a single entry point and a known ending point. There may be multiple exit points within the block however I do know where they will all end up. Using this means that I can create localized variables that will go out of scope though just using brackets without the do { } while (false);
does that as well. However I use the do while because I need the break; capability as well.
I would consider using this style under some of the following conditions. If the business logic that is being implemented requires a set of variables that are shared and referenced by different possible execution pathways which rejoin. If the business logic is complex with multiple states and checks with several levels of if statements and if an error is detected during the processing, an indication to the error is set and the processing is aborted.
The only times that I can think of when I have used this is with something a bit gnarly and this helped to clarify and make the processing abort easier. So basically I was using this similar to throwing an exception with a try/catch.