GitHub
CERT Secure Coding

MSC21-C. Use robust loop termination conditions

C defines < , > , <= , and >= to be relational operators , and it defines == and != to be equality operators .

If a for or while statement uses a loop counter, than it is safer to use a relational operator (such as < ) to terminate the loop than to use an equality operator (such as != ).

Noncompliant Code Example (Equality Operators)

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

Non-compliant code
size_t i;
for (i = 1; i != 10; i += 2) {
  /* ... */
}

Compliant Solution (Relational Operators)

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

Compliant code
size_t i;
for (i = 1; i <= 10; i += 2 ) {
  /* ... */
}

Noncompliant Code Example (Equality Operators)

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:

Non-compliant code
void f(size_t begin, size_t end) {
  size_t i;
  for (i = begin; i != end; ++i) {
    /* ... */
  }
}

Compliant Solution (Relational Operators)

Again, using a relational operator instead of equivalence guarantees loop termination. If begin >= end , the loop never executes its body.

Compliant code
void f(size_t begin, size_t end) {
  size_t i;
  for (i = begin; i < end; ++i) {
    /* ... */
  }
}

Noncompliant Code Example (Boundary Conditions)

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 :

Non-compliant code
void f(size_t begin, size_t step) {
  size_t i;
  for (i = begin; i <= SIZE_MAX; i += step) {
    /* ... */
  }
}

Compliant Solution (Boundary Conditions)

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

Compliant code
void f(size_t begin, size_t step) {
  if (0 < step) {
    size_t i;
    for (i = begin; i <= SIZE_MAX - step; i += step) {
      /* ... */
    }
  }
}

Exceptions

MSC21-C-EX1: If the loop counter is incremented by 1 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 1 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.

Compliant code
size_t i;
for (i = 1; i != 5; ++i) {
  /* ... */
}

Risk Assessment

Testing for exact values runs the risk of a loop terminating much longer than expected or never terminating at all.

Recommendation Severity Likelihood Detectable Repairable Priority Level
MSC21-C Low Unlikely No No P1 L3

Automated Detection

Tool

Version

Checker

Description

Astrée
25.10

Supported: Astrée reports potential infinite loops.
CodeSonar
9.1p0

LANG.STRUCT.LOOP.HR
LANG.STRUCT.LOOP.UB

High risk loop
Potential unbounded loop

Compass/ROSE




LDRA tool suite
9.7.1
510 SPartially implemented
PC-lint Plus

1.4

440, 442, 443,
444, 445, 2650

Partially supported

Polyspace Bug Finder

R2025b

CERT C: Rec. MSC21-C


Checks for loop bounded with tainted value (rec. partially covered)


PVS-Studio

7.42

V621
Security Reviewer - Static Reviewer

6.02

ctuOneDefinitionRuleViolationFully implemented

Search for vulnerabilities resulting from the violation of this rule on the CERT website .

SEI CERT C++ Coding StandardVOID MSC21-CPP. Use inequality to terminate a loop whose counter changes by more than one
CERT Oracle Secure Coding Standard for JavaMSC54-J. Avoid inadvertent wrapping of loop counters