According to the C Standard, 6.8.5.3, paragraph 4 [ISO/IEC 9899:2024],
A switch statement causes control to jump to, into, or past the statement that is the switch body, depending on the value of a controlling expression, and on the presence of a default label and the values of any case labels on or in the switch body. A case or default label is accessible only within the closest enclosing switch statement
...
.
If a programmer declares variables and , initializes them before the first case statement, and try then tries to use them inside any of the case statements, those variables will have scope inside the switch block , but will not be initialized and will consequently contain garbage values. indeterminate values. Reading such values also violates EXP33-C. Do not read uninitialized memory.
Noncompliant Code Example
This noncompliant code example declares variables and contains executable statements before the first case label within the switch statement. :
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h> extern void f(int i); void func(int expr) { switch (expr) { int i = 4; f(i); case 0: i = 17; /* fallsFalls through into default code */ default: printf(“%d"%d\nâ€n", i); } return 0; } |
Implementation Details
On execution of above example on gcc version 4.1.2When the preceding example is executed on GCC 4.8.1, the variable i is instantiated with automatic storage duration within the block, but it is not initialized. Consequently, if the controlling expression expr has a non-zero nonzero value, the call to ((printf()}} will access an indeterminate value of i. Similarly, the call to function will also never get f() is not executed.
i Value of |
|---|
| |
|---|---|
0 | 17 |
Nonzero |
Indeterminate |
Compliant Solution
In this compliant solution, the statements before the first case label occur before the switch statement, improving the predictability and readability of the code.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h> extern void f(int i); int func(int expr) { int/* i = 4; /* Move the code outside the switch block; */ now f(i);the statements * will get executed. */* Now theint statementsi will= get4; executed */ f(i); switch (expr) { case 0: i = 17; /*falls Falls through into default code */ default: printf(“%d"%d\nâ€n", i); } return 0; } |
Risk Assessment
Using test conditions or initializing variables inside the switch block before the first case statement , in a switch block can result in unexpected behavior as the above code will not be executed and undefined behavior 20.
Rule | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level |
|---|
DCL41-C | Medium |
unlikely
medium
P2
L3
References
Unlikely | Yes | Yes | P6 | L2 |
Automated Detection
Tool | Version | Checker | Description | ||||||
| Astrée |
| switch-skipped-code | Fully checked | ||||||
| Axivion Bauhaus Suite |
| CertC-DCL41 | Fully implemented | ||||||
| Clang |
| -Wsometimes-uninitialized | |||||||
| CodeSonar |
| LANG.STRUCT.SW.BAD | Malformed switch Statement | ||||||
| Coverity |
| MISRA C 2004 Rule 15.0 MISRA C 2012 Rule 16.1 | Implemented | ||||||
| Cppcheck Premium |
| premium-cert-dcl41-c | |||||||
| Helix QAC |
| C2008, C2882, C3234 | Fully implemented | ||||||
| Klocwork |
| CERT.DCL.SWITCH.VAR_BEFORE_CASE | Fully implemented | ||||||
| LDRA tool suite |
| 385 S | Fully implemented | ||||||
| Parasoft C/C++test |
| CERT_C-DCL41-a | A switch statement shall only contain switch labels and switch clauses, and no other code | ||||||
| PC-lint Plus |
| 527 | Assistance provided | ||||||
| Polyspace Bug Finder |
| CERT C: Rule DCL41-C | Checks for ill-formed switch statements (rule partially covered) | ||||||
| PVS-Studio |
| V622 | |||||||
| RuleChecker |
| switch-skipped-code | Fully checked | ||||||
| TrustInSoft Analyzer |
| initialisation | Exhaustively detects undefined behavior (see the compliant and the non-compliant example). |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Key here (explains table format and definitions)
Taxonomy | Taxonomy item | Relationship |
|---|---|---|
| MISRA C:2012 | Rule 16.1 (required) | Prior to 2018-01-12: CERT: Unspecified Relationship |
Bibliography
| [ISO/IEC 9899:2024] | 6.8.5.3, "The switch Statement" |
...
MISRA 04 chapter 6.14