As described in depth in rule DCL22-C. Use volatile for data that cannot be cached, a
volatile-qualified variable "shall be evaluated strictly according to the rules of the abstract machine" [ISO/IEC 9899:2011]. In other words, the
volatile qualifier is used to instruct the compiler to not make caching optimizations about a variable.
However, as demonstrated in "Volatiles Are Miscompiled, and What to Do about It" [Eide and Regehr], all tested compilers generated some percentage of incorrect compiled code with regard to
volatile accesses. Therefore, it is necessary to know how your compiler behaves when the standard
volatile behavior is required. The authors also provide a workaround that eliminates some or all of these errors.
Noncompliant Code Example
As demonstrated in Eide and Regehr's work, the following code example compiles incorrectly using GCC 4.3.0 for IA32 and the
-Os optimization flag:
Because the variable
volatile-qualified, it should be accessed 10 times in this program. However, as shown in the compiled object code, it is accessed only once due to a loop-hoisting optimization [Eide and Regehr]:
Eide and Regehr tested a workaround by wrapping
volatile accesses with function calls. They describe it with the intuition that "we can replace an action that compilers empirically get wrong by a different action—a function call—that compilers can get right" [Eide and Regehr]. For example, the workaround for the noncompliant code example would be
The workarounds proposed by
volatile-access bugs in the tested compilers. However, compilers are always changing, so critical sections of code should be compiled as if for deployment, and the compiled object code should be inspected for the correct behavior.
volatile qualifier should be used with caution in mission-critical situations. Always make sure code that assumes certain behavior when using the
volatile qualifier is inspected at the object code level for compiler bugs.
|LDRA tool suite
|[Eide and Regehr]
|"Volatiles Are Miscompiled, and What to Do about It"
|Subclause 6.7.3, "Type Qualifiers"