CertC-DCL41¶
Do not declare variables inside a switch statement before the first case label
Required inputs: IR
According to the C Standard, 6.8.4.2, paragraph 4 [ ISO/IEC 9899:2011],
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.
If a programmer declares variables, initializes them before the first case
statement, and 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 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:
#include <stdio.h>
extern void f(int i);
void func(int expr) {
switch (expr) {
int i = 4;
f(i);
case 0:
i = 17;
/* Falls through into default code */
default:
printf("%d\n", i);
}
}
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 expr |
Output |
|---|---|
| 0 | 17 |
| Nonzero | Indeterminate |
Compliant Solution
In this compliant solution, the statements before the first case label occur
before the
switch statement:
#include <stdio.h>
extern void f(int i);
int func(int expr) {
/*
* Move the code outside the switch block; now the statements
* will get executed.
*/
int i = 4;
f(i);
switch (expr) {
case 0:
i = 17;
/* Falls through into default code */
default:
printf("%d\n", i);
}
return 0;
}
Risk Assessment
Using test conditions or initializing variables before the first case statement
in a
switch block can result in
unexpected
behavior and
undefined
behavior.
| Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
| DCL41-C | Medium | Unlikely | Medium | P4 | L3 |
Related Guidelines
| Taxonomy | Taxonomy item | Relationship |
|---|---|---|
| MISRA C:2012 | Rule 16.1 (required) | Prior to 2018-01-12: CERT: Unspecified Relationship |
Bibliography
| [ ISO/IEC 9899:2011] | 6.8.4.2, "The
switch Statement"
|
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
switch_not_well_formed |
Switch has a statement before the first case label. |
None |
False |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
acceptable_start_items¶
acceptable_start_items : set[bauhaus.ir.PIR_Class_Name] = set()