CertC-EXP40¶
Do not modify constant objects
Required inputs: IR
The C Standard, 6.7.3, paragraph 6 [ IS O/IEC 9899:2011], states
If an attempt is made to modify an object defined with a
const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.
See also undefined behavior 64.
There are existing compiler
implementations
that allow
const-qualified objects to be modified without generating a
warning message.
Avoid casting away
const qualification because doing so makes it possible to modify
const-qualified objects without issuing diagnostics. (See
EXP05-C.
Do not cast away a const qualification and
STR30-C.
Do not attempt to modify string literals for more details.)
Noncompliant Code Example
This noncompliant code example allows a constant object to be modified:
const int **ipp;
int *ip;
const int i = 42;
void func(void) {
ipp = &ip; /* Constraint violation */
*ipp = &i; /* Valid */
*ip = 0; /* Modifies constant i (was 42) */
}
The first assignment is unsafe because it allows the code that follows it to
attempt to change the value of the
const object
i.
Implementation Details
If
ipp,
, and
ipi are declared as automatic variables, this example compiles
without warning with Microsoft Visual Studio 2013 when compiled in C
mode (
/TC) and the resulting program changes the value of
i. GCC 4.8.1 generates a warning but compiles, and the
resulting program changes the value of
i.
If
ipp,
ip, and
i are declared with static storage duration, this program compiles
without warning and terminates abnormally with Microsoft Visual Studio
2013, and compiles with warning and terminates abnormally with GCC 4.8.1.
Compliant Solution
The compliant solution depends on the intent of the programmer. If the intent
is that the value of
i is modifiable, then it should not be declared as a constant, as
in this compliant solution:
int **ipp;
int *ip;
int i = 42;
void func(void) {
ipp = &ip; /* Valid */
*ipp = &i; /* Valid */
*ip = 0; /* Valid */
}
If the intent is that the value of i is not meant to change, then do not write noncompliant code that attempts to modify it.
Risk Assessment
Modifying constant objects through nonconstant references is undefined behavior.
| Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
| EXP40-C | Low | Unlikely | Medium | P2 | L3 |
Related Guidelines
| Taxonomy | Taxonomy item | Relationship |
|---|---|---|
| CERT C Secure Coding Standard | EXP05-C. Do not cast away a const qualification | Prior to 2018-01-12: CERT: Unspecified Relationship |
| CERT C Secure Coding Standard | STR30-C. Do not attempt to modify string literals | Prior to 2018-01-12: CERT: Unspecified Relationship |
Bibliography
| [ ISO/IEC 9899:2011] | Subclause 6.7.3, "Type Qualifiers" |
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
cast_adds_const |
Cast adds const qualification |
None |
False |
cast_adds_volatile |
Cast adds volatile qualification |
None |
False |
implicit_cast_adds_const |
Implicit cast adds const qualification |
None |
False |
implicit_cast_adds_volatile |
Implicit cast adds volatile qualification |
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
check_const¶
check_const : bool = True
check_volatile¶
check_volatile : bool = False