97 lines
2.6 KiB
Plaintext
97 lines
2.6 KiB
Plaintext
== Why is this an issue?
|
|
|
|
A `for` loop with a counter moving away from the end of the specified range is likely a programming mistake.
|
|
|
|
If the intention is to iterate over the specified range, this differs from what the loop does because the counter moves in the wrong direction.
|
|
|
|
If the intention is to have an infinite loop or a loop terminated only by a break statement, there are two problems:
|
|
|
|
1. The loop condition is not infinite because the counter variable will eventually overflow and fulfill the condition. This can take a long time, depending on the data type of the counter.
|
|
2. An infinite loop terminated by a `break` statement should be implemented using a `while` or `do` `while` loop to make the developer's intention clear to the reader.
|
|
|
|
== How to fix it
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
Change the direction of the counter.
|
|
|
|
[source,java,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
for (int i = 10; i > 0; i++) { // Noncompliant, wrong direction
|
|
System.out.println("Hello, world!") // executed ca. 2 billion times
|
|
}
|
|
----
|
|
|
|
[source,java,diff-id=2,diff-type=noncompliant]
|
|
----
|
|
public void doSomething(String [] strings) {
|
|
for (int i = 0; i < strings.length; i--) { // Noncompliant, wrong direction
|
|
String string = strings[i]; // ArrayIndexOutOfBoundsException when i reaches -1
|
|
// ...
|
|
}
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=1,diff-type=compliant]
|
|
----
|
|
for (int i = 10; i > 0; i--) { // Compliant
|
|
System.out.println("Hello, world!") // executed 10 times
|
|
}
|
|
----
|
|
|
|
[source,java,diff-id=2,diff-type=compliant]
|
|
----
|
|
public void doSomething(String [] strings) {
|
|
for (int i = 0; i < strings.length; i++) { // Compliant
|
|
String string = strings[i];
|
|
// ...
|
|
}
|
|
}
|
|
----
|
|
|
|
==== Noncompliant code example
|
|
|
|
If the intention is to have an infinite loop or a loop terminated only by a break statement, use a `while` or a `do` `while` statement instead.
|
|
|
|
[source,java,diff-id=3,diff-type=noncompliant]
|
|
----
|
|
for (int i = 0; i < 0; i++) { // Noncompliant, loop is not infinite
|
|
String event = waitForNextEvent();
|
|
if (event == "terminate") break;
|
|
processEvent(event);
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=3,diff-type=compliant]
|
|
----
|
|
while (true) { // Compliant
|
|
String event = waitForNextEvent();
|
|
if (event == "terminate") break;
|
|
processEvent(event);
|
|
}
|
|
----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* https://wiki.sei.cmu.edu/confluence/x/aTdGBQ[CERT, MSC54-J.] - Avoid inadvertent wrapping of loop counters
|
|
|
|
=== Articles & blog posts
|
|
|
|
* https://en.wikipedia.org/wiki/Integer_overflow[Wikipedia - Integer overflow]
|
|
|
|
|
|
include::../rspecator.adoc[]
|