Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Reworked NCCE/solution, added Eide and Regehr to references page and linked here

...

Wiki Markup
However, as demonstrated in \[[Eide and Regehr|AA. C References#Eide and Regehr]\], all tested compilers generated some percentage of incorrect compiled code with regards to {{volatile}} accesses.  Therefore, it is necessary to know how your compiler behaves when the standard {{volatile}} behavior is required.  There is also a workaround that eliminates some or all of these errors \[[Eide and Regehr|AA. C References#Eide and Regehr]\].

...

Noncompliant Code Example

Wiki Markup
As demonstrated in \[[Eide and Regehr|AA. C References#Eide and Regehr]\], the following code example compiles incorrectly using GCC version 4.3.0 for IA32 and the {{\-Os}} optimization flag:

Code Block
bgColor#ffcccc
const volatile int x;
volatile int y;
void foo(void) {
    for(y = 0; y < 10; y++) {
        int z = x;
    }
}

Wiki Markup
Because the variable {{x}} is {{volatile}}\-qualified, it should be accessed ten times in this program.&nbsp; However, as shown in the compiled object code, it is only accessed once due to a loop-hoisting optimization \[[Eide and Regehr|AA. C References#Eide and Regehr]\]:

Code Block
bgColor#ffcccc
foo:
    movl $0, y
    movl x, %eax
    jmp .L2
.L3:
    movl y, %eax
    incl %eax
    movl %eax, y
.L2:
    movl y, %eax
    cmpl $10, %eax
    jg .L3
    ret

Should x represent a hardware register or some other memory-mapped device that has side effects when accessed, the previous miscompiled code example may produce unexpected behavior.

...

Compliant Solution

Wiki Markup
Eide and Regehr tested a workaround by wrapping {{volatile}} accesses with function calls.&nbsp; 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|AA. C References#Eide and Regehr]\].  For example, the workaround considerfor the followingnoncompliant code example thatwould could be miscompiled:

Code Block

volatile x;
x = x;

Wiki Markup
To work around some of the {{volatile}}-access compiler bugs, wrap both accesses to {{x}} in function calls \[[Eide and Regehr]\]:

bgColor#ccccff
Code Block
int vol_read_int(volatile int *vp) {
    return *vp;
}
volatile int *vol_id_int(volatile int *vp) {
    return vp;
}

const volatile int x;
xvolatile =int xy;
void foo(void) {
    for(*vol_id_int(&xy) = 0; vol_read_int(&y) < 10; *vol_id_int(&y) = vol_read_int(&y) + 1) {
        int z = vol_read_int(&x);
    }
}

Wiki Markup
The workarounds proposed in \[[Eide and Regehr|AA. C References#Eide and Regehr]\] fix many of the {{volatile}}\-access bugs in the tested compilers.&nbsp; 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.

...

Wiki Markup
\[[Eide and Regehr|AA. C References#Eide and Regehr]\] "Volatiles Areare Miscompiledmiscompiled, and Whatwhat to Dodo about Itit"
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.7.3, "Type qualifiers"