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