How does GCC optimize out an unused variable incremented inside a loop?

后端 未结 2 1443
清酒与你
清酒与你 2020-12-08 13:12

I wrote this simple C program:

int main() {
    int i;
    int count = 0;
    for(i = 0; i < 2000000000; i++){
              


        
2条回答
  •  被撕碎了的回忆
    2020-12-08 14:00

    The compiler is even smarter than that. :)

    In fact, it realizes that you aren't using the result of the loop. So it took out the entire loop completely!

    This is called Dead Code Elimination.

    A better test is to print the result:

    #include 
    int main(void) {
        int i; int count = 0;
        for(i = 0; i < 2000000000; i++){
            count = count + 1;
        }
    
        //  Print result to prevent Dead Code Elimination
        printf("%d\n", count);
    }
    

    EDIT : I've added the required #include ; the MSVC assembly listing corresponds to a version without the #include, but it should be the same.


    I don't have GCC in front of me at the moment, since I'm booted into Windows. But here's the disassembly of the version with the printf() on MSVC:

    EDIT : I had the wrong assembly output. Here's the correct one.

    ; 57   : int main(){
    
    $LN8:
        sub rsp, 40                 ; 00000028H
    
    ; 58   : 
    ; 59   : 
    ; 60   :     int i; int count = 0;
    ; 61   :     for(i = 0; i < 2000000000; i++){
    ; 62   :         count = count + 1;
    ; 63   :     }
    ; 64   : 
    ; 65   :     //  Print result to prevent Dead Code Elimination
    ; 66   :     printf("%d\n",count);
    
        lea rcx, OFFSET FLAT:??_C@_03PMGGPEJJ@?$CFd?6?$AA@
        mov edx, 2000000000             ; 77359400H
        call    QWORD PTR __imp_printf
    
    ; 67   : 
    ; 68   : 
    ; 69   : 
    ; 70   :
    ; 71   :     return 0;
    
        xor eax, eax
    
    ; 72   : }
    
        add rsp, 40                 ; 00000028H
        ret 0
    

    So yes, Visual Studio does this optimization. I'd assume GCC probably does too.

    And yes, GCC performs a similar optimization. Here's an assembly listing for the same program with gcc -S -O2 test.c (gcc 4.5.2, Ubuntu 11.10, x86):

            .file   "test.c"
            .section        .rodata.str1.1,"aMS",@progbits,1
    .LC0:
            .string "%d\n"
            .text
            .p2align 4,,15
    .globl main
            .type   main, @function
    main:
            pushl   %ebp
            movl    %esp, %ebp
            andl    $-16, %esp
            subl    $16, %esp
            movl    $2000000000, 8(%esp)
            movl    $.LC0, 4(%esp)
            movl    $1, (%esp)
            call    __printf_chk
            leave
            ret
            .size   main, .-main
            .ident  "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
            .section        .note.GNU-stack,"",@progbits
    

提交回复
热议问题