...
Code Block | ||||
---|---|---|---|---|
| ||||
if (a == b) {
/* ... */
}
else if (a == c) {
/* ... */
}
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
if (a == b) {
/* ... */
}
else if (a == c) {
/* ... */
}
else {
/* handle error condition */
}
|
...
The following noncompliant code example fails to consider all possible cases. Failure to account for all valid values of type Color
will result in a logic error. Since valid values of an enumerated type include all those of its underlying integer type, unless enumeration constants have been provided for all those values, the default
label is appropriate and necessary.
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";
}
}
void g() {
Color unknown = (Color)123;
puts(f(unknown));
}
|
...
Microsoft Visual C++ .NET with /W4
does not warn when assigning an integer value to an enum
type , or when the switch statement does not contain all possible values of the enumeration.
Compliant Solution (Switch)
The following compliant solution below takes care to provide the default
label to handle all valid values of type Color
:
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"; /* necessary */
}
}
|
Note that adding a default case to a switch statement, even when all possible switch labels are specified, is exception an exception (MSC07-EX1) to recommendation MSC07-C. Detect and remove dead code.
An alternative compliant solution to the noncompliant code example above is to provide a return
statement after the switch
statement. Note, however, that this solution may not be appropriate in all situations.
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"; /* necessary */
}
|
...
These two practices have now been merged. A switch
on an enum
type should now contain a case
label for each enum
value , but should also contain a default
label for safety. This is not more difficult to analyze statically.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#define ORIGINYEAR 1980
UINT32 days = /* number 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;
}
}
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
#define ORIGINYEAR 1980
UINT32 days = /* input 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 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Section |
| |||||||||||||
Section | 12 S |
| sectionFully implemented. | |||||||||||
GCC |
| |||||||||||||
Section | Can detect some violations of this recommendation when the | |||||||||||||
Section | Compass/ROSE | |||||||||||||
Section | Can detect some violations of this recommendation. In particular, it flags switch statements that do not have a default clause. ROSE should | also detect "fake switches | ," as well (that is, a chain of | "
| " clause, or they should mathematically cover every possibility. For instance, consider the following: | |||||||||
Code Block | #ccccff | if (x > 0) {
/* ... */
} else if (x < 0) {
/* ... */
} else if (x == 0) {
/* ... */
}
| section||||||||||||
| section LA_UNUSED |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...
CERT C++ Secure Coding Standard: MSC01-CPP. Strive for logical completeness
ISO/IEC TR 17961 (Draft) Use of an implied default in a switch statement [swtchdflt]
ISO/IEC TR 24772 "CLL Switch statements and static analysis"
...