I was looking at some code by an individual and noticed he seems to have a pattern in his functions:
function()
{
The break as goto is probably the answer, but I will put forward one other idea.
Maybe he wanted to have a locally defined variables and used this construct to get a new scope.
Remember while recent C++ allows for {...}
anywhere, this was not always the case.
You can break
out of do{...}while(false)
.
I've seen code like that so you can use break
as a goto
of sorts.
A lot of people point out that it's often used with break as an awkward way of writing "goto". That's probably true if it's written directly in the function.
In a macro, OTOH, do { something; } while (false)
is a convenient way to FORCE a semicolon after the macro invocation, absolutely no other token is allowed to follow.
And another possibility is that there either once was a loop there or iteration is anticipated to be added in the future (e.g. in test-driven development, iteration wasn't needed to pass the tests, but logically it would make sense to loop there if the function needed to be somewhat more general than currently required)
Many answerers gave the reason for do{(...)break;}while(false)
. I would like to complement the picture by yet another real-life example.
In the following code I had to set enumerator operation
based on the address pointed to by data
pointer. Because a switch-case can be used only on scalar types first I did it inefficiently this way
if (data == &array[o1])
operation = O1;
else if (data == &array[o2])
operation = O2;
else if (data == &array[on])
operation = ON;
Log("operation:",operation);
But since Log() and the rest of code repeats for any chosen value of operation I was wandering how to skip the rest of comparisons when the address has been already discovered. And this is where do{(...)break;}while(false)
comes in handy.
do {
if (data == &array[o1]) {
operation = O1;
break;
}
if (data == &array[o2]) {
operation = O2;
break;
}
if (data == &array[on]) {
operation = ON;
break;
}
} while (false);
Log("operation:",operation);
One may wonder why he couldn't do the same with break
in an if
statement, like:
if (data == &array[o1])
{
operation = O1;
break;
}
else if (...)
break
interacts solely with the closest enclosing loop or switch, whether it be a for
, while
or do .. while
type, so unfortunately that won't work.
I agree with most posters about the usage as a thinly disguised goto. Macros have also been mentioned as a potential motivation for writing code in the style.
I have also seen this construct used in mixed C/C++ environments as a poor man's exception. The "do {} while(false)" with a "break" can be used to skip to the end of the code block should something that would normally warrant an exception be encountered in the loop.
I have also sen this construct used in shops where the "single return per function" ideology is enforced. Again, this is in lieu of an explicit "goto" - but the motivation is to avoid multiple return points, not to "skip over" code and continue actual execution within that function.