do {...} while(false)
You can break
out of do{...}while(false)
.
Use cases of do-while-false in C?
It is sometimes used for implementing "structured goto". Inside such do-while
region break
and continue
statements will pass control to the end of the region and continue execution of the code that follows such "cycle".
Another use, already mentioned in the comments, is to work as a compound statement envelope inside macros. The unique feature of do-while
is that it requires a ;
at the end. This allows it to work as a compound statement envelope that will "consume" the following ;
. That feature allows one to write function-like macros with allow the caller to safely place a ;
after them (see here: What does "do { ... } while (0)" do exactly in kernel code?)
do while(false) pattern
It turns a block into a single statement. If you just use a block (i.e. code enclosed in {}
) strange things can happen, for example
#define STUFF() \
{ do_something(); do_something_else(); }
if (cond)
STUFF();
else
//...
the extra semi-colon breaks the syntax. The do {} while(false)
instead is a single statement.
You can find more about this and other macro tricks here.
What is the advantage of a do-while(false)?
Maybe it was done to be able to jump out of the "loop" at any time, e.g:
do
{
...
if (somethingIsWrong) break;
//more code
...
}
while(false);
But as others have said, I wouldn't do it like this.
do { } while (false) in Python
If there's nothing you want to do in between checking the conditions, then the cleanest solution is like this:
if cond1 and cond2 and cond3:
do_thing()
Assuming you do want to do some things in between checking the conditions, here are a few options, in order of subjective Pythonicity.
The cleanest solution is probably to put your code into a function and use return
instead of break
; note that you can write this as a local function, there is no need to expose every function declared in your code. However, if the function is useful enough then you might consider exposing it anyway.
def do_thing_on_conditions():
if not cond1: return
if not cond2: return
if not cond3: return
do_thing()
do_thing_on_conditions()
The do
/while(false)
idiom is essentially a loop structure which iterates once and only once, so you can write it as a for
loop over a sequence of length 1:
for _ in range(1):
if not cond1: break
if not cond2: break
if not cond3: break
do_thing()
Finally, you could do this: but I don't recommend it, because (like the do
/while(false)
idiom) you have to read all the way to the end to know this will only iterate once.
while True:
if not cond1: break
if not cond2: break
if not cond3: break
do_thing()
break
Why use do { ... } while (FALSE); in C++ outside of macros
Well, it does allow you to use the break;
(or continue
) keyword for early exit if you have a need for that for some reason. That would be kinda ugly though. I'd really rather see it moved into its own routine, with the early exit implemented via a return;
statement.
Are do-while-false loops common?
The second snippet just looks wrong. You're effectively re-invented goto.
Anyone reading the first code style will immediately know what's happening, the second style requires more examination, thus makes maintenance harder in the long run, for no real benefit.
Edit, in the second style, you've thrown away the error code, so you can't take any corrective action or display an informative message, log something useful etc....
Python - While false loop
If you want 'while false' functionality, you need not
. Try while not fn:
instead.
Related Topics
Iterative Dfs VS Recursive Dfs and Different Elements Order
Why Does the Enhanced Gcc 6 Optimizer Break Practical C++ Code
Do Current X86 Architectures Support Non-Temporal Loads (From "Normal" Memory)
What Is Going on with 'Gets(Stdin)' on the Site Coderbyte
How Portable Is End Iterator Decrement
Printing Values of All Fields in a C++ Structure
How to Add and Subtract 128 Bit Integers in C or C++ If My Compiler Does Not Support Them
<Iostream> VS. <Iostream.H> VS. "Iostream.H"
Split an Integer into Its Digits C++
Sorting a Std::Vector<Std::Pair<Std::String,Bool>> by the String
How Define an Array of Function Pointers in C
Where Do I Find the Definition of Size_T
When Should You Use the "This" Keyword in C++
Pure Virtual Functions May Not Have an Inline Definition. Why
How to Return in Void Function
Why Reference Size Is Always 4 Bytes - C++
How to Redirect Output to a File with Createprocess
Calling Initializer_List Constructor via Make_Unique/Make_Shared