ACCU Home page ACCU Conference Page
Search Contact us ACCU at Flickr ACCU at GitHib ACCU at Facebook ACCU at Linked-in ACCU at Twitter Skip Navigation

pinQM Bites: looping for-ever

Overload Journal #132 - April 2016 + Programming Topics   Author:
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 breaks. (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.

Overload Journal #132 - April 2016 + Programming Topics