Never-ending loop constructs can confound user and compiler in subtle ways. Matthew Wilson offers advice to maximise portability and transparency.
TL;DR:
do
not use
while
to loop
for(;;)
ever
Bite:
Sometimes we want to use a loop that runs forever. This might be for a worker thread that simply waits for receipt of work, performs the work, and waits again, ad infinitum.
At other times the invariant for a loop may be too complex to be expressed transparently as a single expression in the loop-construct’s loop invariant clause, instead being handled using one or more
break
s. (Note: such cases should always give one pause for thought, and to question whether the whole construct is too complex and should be broken down.)
Either way, we want a loop construct that loops forever, which means we want a loop invariant that is always true.
One common method to achieve this is as follows:
/* Commonly seen in C */ while(1) { . . . things that are repeated forever }
Or the equivalent:
/* Commonly seen in C++ */ while(true) { . . . things that are repeated forever }
There are two problems with this. First, the practical. Some compilers issue a warning about the use of a constant within the invariant of a loop statement. For example, the Visual C++ compiler will issue warning 4127 “ conditional expression is constant ”. Since we always want to use maximum warnings wherever possible, and we always want to treat warnings as errors, this construct is something to avoid to ensure portability and maximum effective use of warnings.
Second, the philosophical. To be sure, this is a question of perception/taste (but I know others share my apprehension): it’s just kind of weird and clumsy to say “
loop for as long as
true
is true
”.
The answer to both concerns is the same: instead use a
for
-statement with a blank invariant, which is interpreted as “forever” (something for which it is designed):
for(;;) { . . . things that are repeated forever }
Further, you’re not required to have a fully empty
for
-statement to have infinite looping. The following will loop forever while providing you some indication as to how many loops have been done:
for(int i = 0;; ++i) { . . . things that are repeated forever }
Just be aware that this will wrap around eventually (and repeatedly).
Afterthoughts
There are other aspects to the issue of constant expressions in loop expressions. Coming to a Bite-near-you sometime soon.