Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Wiki Markup
As demonstrated in \[[Eide and Regehr|AA. Bibliography#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
langc
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. However, as shown in the compiled object code, it is only accessed once due to a loop-hoisting optimization \[[Eide and Regehr|AA. Bibliography#Eide and Regehr]\]:

Code Block
bgColor#ffcccc
langc
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

...

Wiki Markup
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|AA. Bibliography#Eide and Regehr]\]. For example, the workaround for the noncompliant code example would be

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

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

...