Do not cast away a volatile qualification on a variable type. Casting away the volatile qualification permits the compiler to optimize away operations on the volatile type, thereby negating the use of the volatile keyword in the first place.
Non-Compliant Code Example
In this example, a volatile object is accessed through a non-volatile-qualified reference, resulting in undefined behavior.
static volatile int **ipp; static int *ip; static volatile int i = 0; printf("i = %d.\n", i); ipp = &ip; /* produces warnings in modern compilers */ ipp = (int**) &ip; /* constraint violation */ *ipp = &i; /* valid */ if (*ip != 0) { /* valid */ /* ... */ }
The assignment ipp = &ip
is unsafe because it would allow the valid code that follows to reference the value of the volatile object i
through the non-volatile qualified reference ip
. In this example, the compiler may optimize out the entire if
block because it is not possible that i != 0
if i
is not volatile.
Implementation Details
This example compiles without warning on Microsoft Visual C++ .NET (2003) and on MS Visual Studio 2005.
This example does not compile on MS Visual Studio 2008. The error message is
error C2440: '=' : cannot convert from 'int **' to 'volatile int **'
Version 3.2.2 and Version 4.1.3 of the GCC compiler generate a warning but compile successfully.
Compliant Solution
In this compliant solution, ip
is declared as volatile.
static volatile int **ipp; static volatile int *ip; static volatile int i = 0; printf("i = %d.\n", i); ipp = &ip; *ipp = &i; if (*ip != 0) { /* ... */ }
Risk Assessment
Casting away volatile allows access to an object through a non-volatile reference. This can result in undefined and perhaps unintended program behavior.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
EXP32-C |
low |
likely |
medium |
P6 |
L2 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[ISO/IEC 9899:1999]] Section 6.7.3, "Type qualifiers," and Section 6.5.16.1, "Simple assignment"
[[ISO/IEC PDTR 24772]] "HFC Pointer casting and pointer type changes"
[[MISRA 04]] Rule 11.5
VOID EXPxx-C. Do not modify constant values 03. Expressions (EXP) EXP33-C. Do not reference uninitialized memory