Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This noncompliant code example appears to have 5 iterations, but, in fact, the loop never terminates.

Code Block
bgColor#FFCCCC
langc
size_t i;
for (i = 1; i != 10; i += 2) {
  /* ... */
}

...

Using the relational operator <= instead of an equality operator guarantees loop termination.

Code Block
bgColor#ccccff
langc
size_t i;
for (i = 1; i <= 10; i += 2 ) {
  /* ... */
}

...

It is also important to ensure termination of loops where the start and end values are variables that might not be properly ordered. The following function assumes that begin < end; if this is not the case, the loop will never terminate.

Code Block
bgColor#ffcccc
langc
void f(size_t begin, size_t end) {
  size_t i;
  for (i = begin; i != end; ++i) {
    /* ... */
  }
}

...

Numerical comparison operators do not always ensure loop termination when comparing against the minimum or maximum representable value of a type, such as SIZE_MAX:

Code Block
bgColor#ffcccc
langc
void f(size_t begin, size_t step) {
  size_t i;
  for (i = begin; i <= SIZE_MAX; i += step) {
    /* ... */
  }
}

...

A compliant solution is to compare against the difference between the maximum representable value of a type and the increment.

Code Block
bgColor#ccccff
langc
void f(size_t begin, size_t step) {
  if (0 < step) {
    int i;
    for (i = begin; i <= INT_MAX - step; i += step) {
      /* ... */
    }
  }
}

...

MSC21-EX1: If the loop counter is incremented by one on each iteration, and it is known that the starting value of a loop is less than or equal to the ending value, then an equality operator may be used to terminate the loop. Likewise, if the loop counter is decremented by one on each iteration, and it is known that the starting value of the loop is greater than or equal to the ending value, then an equality operator may be used to terminate the loop.

Code Block
bgColor#ccccff
langc
size_t i;
for (i = 1; i != 5; ++i) {
  /* ... */
}

...