Why doesn't gcc remove this check of a non-volatile variable?
Posted
by Thomas
on Stack Overflow
See other posts from Stack Overflow
or by Thomas
Published on 2010-03-25T18:48:35Z
Indexed on
2010/03/25
18:53 UTC
Read the original article
Hit count: 330
This question is mostly academic. I ask out of curiosity, not because this poses an actual problem for me.
Consider the following incorrect C program.
#include <signal.h>
#include <stdio.h>
static int running = 1;
void handler(int u) {
running = 0;
}
int main() {
signal(SIGTERM, handler);
while (running)
;
printf("Bye!\n");
return 0;
}
This program is incorrect because the handler interrupts the program flow, so running
can be modified at any time and should therefore be declared volatile
. But let's say the programmer forgot that.
gcc 4.3.3, with the -O3
flag, compiles the loop body (after one initial check of the running
flag) down to the infinite loop
.L7:
jmp .L7
which was to be expected.
Now we put something trivial inside the while
loop, like:
while (running)
putchar('.');
And suddenly, gcc does not optimize the loop condition anymore! The loop body's assembly now looks like this (again at -O3
):
.L7:
movq stdout(%rip), %rsi
movl $46, %edi
call _IO_putc
movl running(%rip), %eax
testl %eax, %eax
jne .L7
We see that running
is re-loaded from memory each time through the loop; it is not even cached in a register. Apparently gcc now thinks that the value of running
could have changed.
So why does gcc suddenly decide that it needs to re-check the value of running
in this case?
© Stack Overflow or respective owner