...
The examples here fall under the exception MSC17:EX2 in MSC17-C. Finish every set of statements associated with a case label with a break statement.
Noncompliant Code Example
This example shows the use of the switch statment to jump into a for loop.
Code Block | ||
---|---|---|
| ||
int f(int i) { int j=0; switch (i) { case 1: for(j=0;j<10;j++) { // no break, process case 2 as well case 2: // switch jumps inside the for block j++; // no break, process case 3 as well case 3: j++; } break; default: // default action break; } return j; } |
Implementation Details
When i=1, this executes the entire for loop. When i=2, two increments to j are made before the loop starts. When i=3, one increment to j is made before the loop starts. The default case is no loop. Consequently, the function has the following behavior:
| |
---|---|
1 | 12 |
2 | 12 |
3 | 11 |
other values | 0 |
Compliant Code Example
The compliant example separates the switch and for blocks.
Code Block | ||
---|---|---|
| ||
int f(int i) { int j=0; switch (i) { case 1: // no break, process case 2 as well case 2: j++; // no break, process case 3 as well case 3: j++; break; default: // default action return j; } for(j++;j<10;j++) { j+=2; } return j; } |
Noncompliant Code Example (Duff's Device)
Duff's Device is a curious optimization applied to code intended to perform a serial copy. That is, it copies a a series of bytes into one memory output in turn. A simple code to do this would be:
...
Many people ... have said that the worst feature of C is that switches don't break automatically before each case label. This code forms some sort of argument in that debate, but I'm not sure whether it's for or against.
Compliant Code Example (Duff's Device)
This is an alternate implemention of Duff's Device which separates the switch statement and loop.
Code Block | ||
---|---|---|
| ||
int n = (count + 7) / 8; switch (count % 8) { case 0: *to = *from++; /* fall through */ case 7: *to = *from++; /* fall through */ case 6: *to = *from++; /* fall through */ case 5: *to = *from++; /* fall through */ case 4: *to = *from++; /* fall through */ case 3: *to = *from++; /* fall through */ case 2: *to = *from++; /* fall through */ case 1: *to = *from++; /* fall through */ } while (--n > 0) { *to = *from++; *to = *from++; *to = *from++; *to = *from++; *to = *from++; *to = *from++; *to = *from++; *to = *from++; } |
Risk Assessment
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC20-C | medium | probable | medium | P8 | L2 |
Other Languages
This rule appears in the C++ Secure Coding Standard as MSC21-CPP. Do not use a switch statement to transfer control into a complex block.
References
Wiki Markup |
---|
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.8.6.1 "The goto statement" [MISRA 04|AA. C References#ISO/MISRA 04] Rule 15.1 [Tom Duff on Duff's Device|http://www.lysator.liu.se/c/duffs-device.html] |