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 inequality equality operator (operator such as !=
).
Anchor |
---|
| nce_inequality_multistep |
---|
| nce_inequality_multistep |
---|
|
Noncompliant Code Example (Equality Operators)
This noncompliant code example may appear appears to have 5 have five iterations, but in fact, the loop never terminates.:
Code Block |
---|
|
size_t
int i;
for (i = 1; i != 10; i += 2) {
/* ... */
}
|
Anchor |
---|
| cs_relational_multistep |
---|
| cs_relational_multistep |
---|
|
Compliant Solution (Relational
...
Operators)
Using the relational operator <=
instead of an equality operator guarantees loop termination.:
Code Block |
---|
|
size_t
int i;
for (i = 1; i <= 10; i += 2 ) {
/* ... */
}
|
Anchor |
---|
| nce_inequality |
---|
| nce_inequality |
---|
|
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.:
Code Block |
---|
|
void f(intsize_t begin, intsize_t end) {
intsize_t i;
for (i = begin; i != end; ++i) {
/* ... */
}
}
|
Anchor |
---|
| cs_relational |
---|
| cs_relational |
---|
|
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(intsize_t begin, intsize_t end) {
intsize_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 INT_MIN
or INTSIZE_MAX
:
Code Block |
---|
|
void f(intsize_t begin, intsize_t step) {
intsize_t i;
for (i = begin; i <= INTSIZE_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.:
Code Block |
---|
|
void f(intsize_t begin, intsize_t step) {
if (0 < step) {
intsize_t i;
for (i = begin; i <= INTSIZE_MAX - step; i += step) {
/* ... */
}
}
}
|
Exceptions
MSC21-C-EX1: If the loop counter for a loop is 1is 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 the equals an equality operator may be used to terminate the loop. Likewise, if the loop counter is -1decremented 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 the equals an equality operator may be used to terminate the loop.
Code Block |
---|
|
size_t
int 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 | Remediation Cost | Priority | Level |
---|
MSC21-C |
low unlikely low P1 Automated Detection
Tool | Version | Checker | Description |
---|
Astrée | |
| Supported: Astrée reports potential infinite loops. |
CodeSonar | | LANG.STRUCT.LOOP.HR
|
ROSE can detect violations of this rule.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
Related Guidelines
...
...
...
Image Added Image Added
...
References
Wiki Markup |
---|
\[[MISRA 04|AA. References#MISRA 04]\] |
Image Removed 49. Miscellaneous (MSC) Image Modified