C99 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 using to use an equality operator (such as !=
).
...
This noncompliant code example appears to have 5 have five iterations, but , in fact, the loop never terminates.:
Code Block | ||||
---|---|---|---|---|
| ||||
size_t i;
for (i = 1; i != 10; i += 2) {
/* ... */
}
|
Anchor | ||||
---|---|---|---|---|
|
Compliant Solution (Relational
...
Operators)
Using the relational operator <=
instead of an equality operator guarantees loop termination.:
Code Block | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
void f(size_t begin, size_t end) {
size_t i;
for (i = begin; i != end; ++i) {
/* ... */
}
}
|
Anchor | ||||
---|---|---|---|---|
|
Compliant Solution (Relational
...
Operators)
Again, using a relational operator instead of equivalence guarantees loop termination. If begin >= end
, the loop never executes its body.
Code Block | ||||
---|---|---|---|---|
| ||||
void f(size_t begin, size_t end) {
size_t i;
for (i = begin; i < end; ++i) {
/* ... */
}
}
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
void f(size_t begin, size_t step) { if (0 < step) { intsize_t i; for (i = begin; i <= INTSIZE_MAX - step; i += step) { /* ... */ } } } |
Anchor | ||||
---|---|---|---|---|
|
Exceptions
MSC21-C-EX1: If the loop counter is incremented by one 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 one 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.
Code Block | ||||
---|---|---|---|---|
| ||||
size_t i;
for (i = 1; i != 5; ++i) {
/* ... */
}
|
...
Testing for exact values runs the risk of a loop terminating much longer than expected , or never terminating at all.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC21-C |
Low |
Unlikely |
Low | P3 | L3 |
Automated Detection
Tool | Version | Checker | Description |
---|
Section |
---|
ROSE |
Astrée |
| Supported: Astrée reports potential infinite loops. | |||||||
CodeSonar |
| LANG.STRUCT.LOOP.HR | High risk loop | ||||||
Compass/ROSE | |||||||||
LDRA tool suite |
| 510 S | Partially implemented | ||||||
PC-lint Plus |
| 440, 442, 443, | Partially supported | ||||||
Polyspace Bug Finder |
| Checks for loop bounded with tainted value (rec. partially covered) | |||||||
PVS-Studio |
| V621 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
...
...
...
...
...
...
...
...
Bibliography
ISO/IEC 9899:1999 Section 6.5.8 "Relational operators" and 6.5.9 "Equality operators"