Control Statement Braces
ID |
csharp.control_statement_braces |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Best Practice |
Language |
CSharp |
Tags |
best-practice |
Description
Reports two related defects. First, if, else, while, for, foreach and do control
statements whose body is a single statement written without surrounding braces. Second, the
statement that follows such an unbraced control statement when it is indented as though it
were part of the body, even though it runs unconditionally.
Rationale
Unbraced body. An unbraced control-statement body is fragile. When a second statement is added later it silently falls outside the control flow even though the indentation suggests otherwise — the "goto fail" family of bugs. Always bracing the body also keeps debug-stepping aligned with the condition and removes any ambiguity about which statements the branch or loop covers.
Misleadingly indented continuation. The same bug, already committed. C# ignores layout, so
only the first statement after an unbraced if belongs to it; a second statement indented to
the same column runs on every path regardless of the condition. Nothing in the compiler
complains, and the indentation actively hides the mistake from reviewers, who read the block
as the author intended it rather than as the language defines it. This is reported only when
the control statement has no braces — a braced body states its extent explicitly and cannot
mislead — and only when the following statement starts on a later line at or past the column
of the body.
if (ready)
Start(); // FLAW, unbraced if body
while (HasNext())
Advance(); // FLAW, unbraced while body
for (int i = 0; i < n; i++)
Process(i); // FLAW, unbraced for body
if (ready)
Start(); // FLAW, unbraced if body
Log("started"); // FLAW, indented like the body but runs unconditionally
if (ready)
{
Start(); // OK
Log("started"); // OK, the braces say what belongs to the branch
}
if (ready)
Start(); // FLAW, unbraced if body
Log("started"); // OK, the layout matches what the code does
Remediation
Wrap the body in a block with { }, even when it currently contains a single statement. Where
a following statement is indented as if it belonged to the body, decide which behaviour was
meant: move it inside the new block if it should be conditional, or outdent it to the level of
the control statement if it should not.