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: 327

Filed under:
|
|
|

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

Related posts about c

    Related posts about volatile