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 their value will be taken garbage. Any unexpected result can follow because of the above behavior.
Non Compliant Code:
not be initialized and will consequently contain 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:In the example mentioned below, the variable i will be instantiated with automatic storage duration within the block, but it’s never initialized. Thus, if the controlling expression has a non-zero value, the cause to printf will access an indeterminate value of i. Similarly, the call to function will also never get executed.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h> intextern funcvoid f( int expr i); { void func(int expr) { switch (expr) { int i = 4; f(i); case 0: i = 17; /*falls Falls through into default code */ default: printf(“%d"%d\nâ€n", i); } return 0; } } |
Implementation Details
When 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 nonzero value, the call to printf() will access an indeterminate value of i. Similarly, the call to f() is not executed.
Value of |
|
|---|---|
0 | 17 |
Nonzero | Indeterminate |
Compliant Solution
In the this compliant solution, by moving the statements before the first case statement outside the switch block, the execution can be ensured and result in an expected behavior.label occur before the switch statement:
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h> extern void f(int i); int func(int expr) { int i =/* 4; * // Move the code outside the switch block f(i); now the statements * will get // Now the statements will get executed switchexecuted. */ int i = 4; 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 behaviour as the above code will not be executedbehavior and undefined behavior 20.
Rule | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level | ||||
|---|---|---|---|---|---|---|
DCL41-C | Medium | 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 |
Medium
unlikely
medium
P2
| 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" |
...