...
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