...
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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
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); } } |
...