Loop Condition Never True
ID |
csharp.loop_condition_never_true |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
dead-code, loop, reliability |
Description
Reports a for loop whose condition is already false when the loop is entered, so its body never
runs: for (int i = 0; i < 0; i)`, `for (int i = 5; i < 5; i), for (int i = 0; i > 10; i++).
Rationale
A loop whose condition fails on entry is a block of code that looks live but never executes. Nothing warns about it, tests that cover the surrounding method still pass, and the body silently contributes nothing — the effect the author expected simply does not happen. The usual causes are an off-by-one edit to the bound, a copy-paste that left the wrong comparison operator, and a starting value that was changed without revisiting the condition.
The rule fires only where both values are known from the loop header itself: the header gives a variable an integer literal value — by declaring it, or by assigning to one declared just above the loop — and the condition compares that same variable against another integer literal. A header declaring several variables is read in full, so the condition may name any of them. A bound or a starting value that is computed elsewhere is not analysed, so what the rule reports is decided, not guessed.
public void NeverRuns()
{
for (int i = 0; i < 0; i++) // FLAW — 0 < 0 is false; the body is dead
{
Log(i);
}
}
public void NeverRunsEqualBound()
{
for (int i = 5; i < 5; i++) // FLAW — 5 < 5 is false; `<=` was probably meant
{
Log(i);
}
}
public void RunsOnce()
{
for (int i = 0; i <= 0; i++) // OK — runs for i == 0
{
Log(i);
}
}
public void RunsToBound(int limit)
{
for (int i = 0; i < limit; i++) // OK — the bound is not known here
{
Log(i);
}
}
Remediation
Work out which of the two values is wrong. If the body is meant to run for the starting value, widen
the comparison (i ⇐ 5 rather than i < 5) or correct the bound. If the comparison operator points
the wrong way, flip it. If the loop is genuinely obsolete, delete it along with its body rather than
leaving unreachable code behind.