...
This noncompliant code example fails to test for conditions where a
is neither b
nor c
. This behavior may be the correct in this case, but failure to account for all the values of a
can result in logic errors if a
unexpectedly assumes a different value.
...
Code Block | ||||
---|---|---|---|---|
| ||||
if (a == b) { /* ... */ } else if (a == c) { /* ... */ } else { /* handleHandle error condition */ } |
Noncompliant Code Example (Switch)
...
Code Block | ||||
---|---|---|---|---|
| ||||
typedef enum { Red, Green, Blue } Color; const char* f(Color c) { switch (c) { case Red: return "Red"; case Green: return "Green"; case Blue: return "Blue"; default: return "Unknown color"; /* necessaryNecessary */ } } |
Note that adding a default case to a switch
statement, even when all possible switch labels are specified, is an exception (MSC07-EX1) to MSC07-C. Detect and remove dead code.
...
Code Block | ||||
---|---|---|---|---|
| ||||
typedef enum { Red, Green, Blue } Color; const char* f(Color c) { switch (c) { case Red: return "Red"; case Green: return "Green"; case Blue: return "Blue"; } return "Unknown color"; /* necessaryNecessary */ } |
Historical Discussion
...
Code Block | ||||
---|---|---|---|---|
| ||||
#define ORIGINYEAR 1980 UINT32 days = /* numberNumber of days since January 1, 1980 */ int year = ORIGINYEAR; /* ... */ while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } } else { days -= 365; year += 1; } } |
...
The following proposed rewrite is provided by at http://wwwwinjade.aeroxp.orgnet/2009/01/lesson-on-infinite-loops. The loop is guaranteed to exit, because days
decreases for each iteration of the loop, unless the while
condition fails , and the loop terminates.
Code Block | ||||
---|---|---|---|---|
| ||||
#define ORIGINYEAR 1980 UINT32 days = /* inputInput parameter */ int year = ORIGINYEAR; /* ... */ int daysThisYear = (IsLeapYear(year) ? 366 : 365); while (days > daysThisYear) { days -= daysThisYear; year += 1; daysThisYear = (IsLeapYear(year) ? 366 : 365); } |
...
Tool | Version | Checker | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Include Page | LDRA_V | 12 S | Fully implemented. | GCC | |||||||||||
Include Page | GCC_V | GCC_V | Can detect some violations of this recommendation when the | ||||||||||||
Compass/ROSE | Can detect some violations of this recommendation. In particular, it flags switch statements that do not have a default clause. ROSE should detect "fake switches" as well (that is, a chain of if (x > 0) { /* ... */ } else if (x < 0) { /* ... */ } else if (x == 0) { /* ... */ } | ||||||||||||||
GCC |
| Can detect some violations of this recommendation when the | |||||||||||||
Klocwork |
| LA_UNUSED | |||||||||||||
| 12 S | Fully implemented. | |||||||||||||
PRQA QA-C |
| 0597 | Fully implemented |
...
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
...
MSC01-CPP. Strive for logical completeness | |
ISO/IEC TS 17961 (Draft) | Use of an implied default in a switch statement [swtchdflt] |
ISO/IEC TR 24772 |
...
Switch |
...
Statements and Static Analysis [CLL] |
Bibliography
...
[Hatton 1995] | Section 2.7.2, "Errors of |
...
Omission and |
...
Addition" | |
[Viega 2005] | Section 5.2.17, "Failure to |
...
Account for |
...
Default Case in |
...
Switch" | |
[Zadegan 2009] | "A Lesson on Infinite Loops" |
http://www.aeroxp.org/2009/01/lesson-on-infinite-loops] for analysis on the Zune 30 bug